diff --git a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepA.cc b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepA.cc index 8e4297648d..49bf0eb111 100644 --- a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepA.cc +++ b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepA.cc @@ -16,551 +16,3548 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_acquisition_MsgAcqResultDepA0 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepA0() { + assign(test_msg_.cf, 8241.943359375); + assign(test_msg_.cp, 727.0); + assign(test_msg_.prn, 8); + assign(test_msg_.snr, 14.5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x4402; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { + 85, 21, 0, 195, 4, 13, 0, 0, 104, 65, 0, + 192, 53, 68, 198, 199, 0, 70, 8, 2, 68, + }; + uint8_t encoded_payload_[13] = { + 0, 0, 104, 65, 0, 192, 53, 68, 198, 199, 0, 70, 8, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepA1 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepA1() { + assign(test_msg_.cf, 749.2676391601562); + assign(test_msg_.cp, 359.5); + assign(test_msg_.prn, 9); + assign(test_msg_.snr, 15.300000190734863); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x1bdb; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { + 85, 21, 0, 195, 4, 13, 205, 204, 116, 65, 0, + 192, 179, 67, 33, 81, 59, 68, 9, 219, 27, + }; + uint8_t encoded_payload_[13] = { + 205, 204, 116, 65, 0, 192, 179, 67, 33, 81, 59, 68, 9, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepA2 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepA2() { + assign(test_msg_.cf, -6493.65283203125); + assign(test_msg_.cp, 40.5); + assign(test_msg_.prn, 11); + assign(test_msg_.snr, 18.100000381469727); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x2396; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { + 85, 21, 0, 195, 4, 13, 205, 204, 144, 65, 0, + 0, 34, 66, 57, 237, 202, 197, 11, 150, 35, + }; + uint8_t encoded_payload_[13] = { + 205, 204, 144, 65, 0, 0, 34, 66, 57, 237, 202, 197, 11, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepA3 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepA3() { + assign(test_msg_.cf, -999.0234985351562); + assign(test_msg_.cp, 548.5); + assign(test_msg_.prn, 12); + assign(test_msg_.snr, 15.300000190734863); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x7692; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { + 85, 21, 0, 195, 4, 13, 205, 204, 116, 65, 0, + 32, 9, 68, 129, 193, 121, 196, 12, 146, 118, + }; + uint8_t encoded_payload_[13] = { + 205, 204, 116, 65, 0, 32, 9, 68, 129, 193, 121, 196, 12, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepA4 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepA4() { + assign(test_msg_.cf, 4745.361328125); + assign(test_msg_.cp, 780.5); + assign(test_msg_.prn, 14); + assign(test_msg_.snr, 15.300000190734863); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA0, Test) { - uint8_t encoded_frame[] = { - 85, 21, 0, 195, 4, 13, 0, 0, 104, 65, 0, - 192, 53, 68, 198, 199, 0, 70, 8, 2, 68, + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = 8241.943359375; - test_msg.cp = 727.0; - test_msg.prn = 8; - test_msg.snr = 14.5; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 8241.94335938 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 8241.94335938, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 727.0 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 727.0, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 8) - << "incorrect value for last_msg_.prn, expected 8, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 14.5 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 14.5, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 21, 0, 195, 4, 13, 205, 204, 116, 65, 0, - 192, 179, 67, 33, 81, 59, 68, 9, 219, 27, + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } }; - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = 749.2676391601562; - test_msg.cp = 359.5; - test_msg.prn = 9; - test_msg.snr = 15.300000190734863; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 749.26763916 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 749.26763916, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 359.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 359.5, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 9) - << "incorrect value for last_msg_.prn, expected 9, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 15.3000001907 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 15.3000001907, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x4b17; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 21, 0, 195, 4, 13, 205, 204, 144, 65, 0, - 0, 34, 66, 57, 237, 202, 197, 11, 150, 35, - }; + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = -6493.65283203125; - test_msg.cp = 40.5; - test_msg.prn = 11; - test_msg.snr = 18.100000381469727; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -6493.65283203 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -6493.65283203, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 40.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 40.5, is " << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 11) - << "incorrect value for last_msg_.prn, expected 11, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 18.1000003815 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 18.1000003815, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 21, 0, 195, 4, 13, 205, 204, 116, 65, 0, - 32, 9, 68, 129, 193, 121, 196, 12, 146, 118, - }; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = -999.0234985351562; - test_msg.cp = 548.5; - test_msg.prn = 12; - test_msg.snr = 15.300000190734863; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -999.023498535 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -999.023498535, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 548.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 548.5, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 12) - << "incorrect value for last_msg_.prn, expected 12, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 15.3000001907 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 15.3000001907, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA4, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { 85, 21, 0, 195, 4, 13, 205, 204, 116, 65, 0, 32, 67, 68, 228, 74, 148, 69, 14, 23, 75, }; + uint8_t encoded_payload_[13] = { + 205, 204, 116, 65, 0, 32, 67, 68, 228, 74, 148, 69, 14, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = 4745.361328125; - test_msg.cp = 780.5; - test_msg.prn = 14; - test_msg.snr = 15.300000190734863; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 4745.36132812 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 4745.36132812, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 780.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 780.5, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 14) - << "incorrect value for last_msg_.prn, expected 14, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 15.3000001907 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 15.3000001907, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepA5 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepA5() { + assign(test_msg_.cf, -499.5117492675781); + assign(test_msg_.cp, 584.5); + assign(test_msg_.prn, 0); + assign(test_msg_.snr, 163.22222900390625); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_a, + sizeof(msg->acq_result_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xcfcc; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 13; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_a_t &lesser, + const sbp_msg_acq_result_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepA, &wrapped_greater, &wrapped_lesser), + 0); -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepA5, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_a_t test_msg_{}; + uint8_t encoded_frame_[13 + 8] = { 85, 21, 0, 195, 4, 13, 228, 56, 35, 67, 0, 32, 18, 68, 129, 193, 249, 195, 0, 204, 207, }; + uint8_t encoded_payload_[13] = { + 228, 56, 35, 67, 0, 32, 18, 68, 129, 193, 249, 195, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + + for (uint8_t i = 0; i < 13; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_acq_result_dep_a_t test_msg{}; - test_msg.cf = -499.5117492675781; - test_msg.cp = 584.5; - test_msg.prn = 0; - test_msg.snr = 163.22222900390625; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_a_t lesser = info.test_msg; + sbp_msg_acq_result_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_A"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[13]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 13); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 13), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 13); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + sbp::State state{}; + state.set_reader(&reader); - while (dummy_rd_ < dummy_wr_) { - process(); + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -499.511749268 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -499.511749268, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 584.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 584.5, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.prn, 0) - << "incorrect value for last_msg_.prn, expected 0, is " << last_msg_.prn; - EXPECT_LT((last_msg_.snr * 100 - 163.222229004 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 163.222229004, is " - << last_msg_.snr; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepB.cc b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepB.cc index 975902b063..7e2a0213ad 100644 --- a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepB.cc +++ b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepB.cc @@ -16,506 +16,3029 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_acquisition_MsgAcqResultDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_acquisition_MsgAcqResultDepB0 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepB0() { + assign(test_msg_.cf, 4995.1171875); + assign(test_msg_.cp, 322.0); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 9); + assign(test_msg_.snr, 36.66360855102539); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_b, + sizeof(msg->acq_result_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xc350; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_b_t &lesser, + const sbp_msg_acq_result_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepB0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_b_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 20, 0, 246, 215, 16, 137, 167, 18, 66, 0, 0, 161, 67, 240, 24, 156, 69, 9, 0, 0, 0, 80, 195, }; + uint8_t encoded_payload_[16] = { + 137, 167, 18, 66, 0, 0, 161, 67, 240, 24, 156, 69, 9, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_B"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); - sbp_msg_acq_result_dep_b_t test_msg{}; - test_msg.cf = 4995.1171875; - test_msg.cp = 322.0; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 9; - test_msg.snr = 36.66360855102539; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 4995.1171875 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 4995.1171875, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 322.0 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 322.0, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 9) - << "incorrect value for last_msg_.sid.sat, expected 9, is " - << last_msg_.sid.sat; - EXPECT_LT((last_msg_.snr * 100 - 36.663608551 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 36.663608551, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepB1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepB1 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepB1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepB1() { + assign(test_msg_.cf, -8241.943359375); + assign(test_msg_.cp, 843.0); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 3); + assign(test_msg_.snr, 36.16875457763672); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_b, + sizeof(msg->acq_result_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8f95; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_b_t &lesser, + const sbp_msg_acq_result_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepB1, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_b_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 20, 0, 246, 215, 16, 206, 172, 16, 66, 0, 192, 82, 68, 198, 199, 0, 198, 3, 0, 0, 0, 149, 143, }; + uint8_t encoded_payload_[16] = { + 206, 172, 16, 66, 0, 192, 82, 68, 198, 199, 0, 198, 3, 0, 0, 0, + }; +}; - sbp_msg_acq_result_dep_b_t test_msg{}; - test_msg.cf = -8241.943359375; - test_msg.cp = 843.0; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 3; - test_msg.snr = 36.16875457763672; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -8241.94335938 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -8241.94335938, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 843.0 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 843.0, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 3) - << "incorrect value for last_msg_.sid.sat, expected 3, is " - << last_msg_.sid.sat; - EXPECT_LT((last_msg_.snr * 100 - 36.1687545776 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 36.1687545776, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepB2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepB2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepB2, Test) { - uint8_t encoded_frame[] = { - 85, 20, 0, 246, 215, 16, 228, 27, 15, 66, 0, 128, - 70, 68, 228, 74, 148, 69, 18, 0, 0, 0, 179, 155, - }; + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_acq_result_dep_b_t test_msg{}; - test_msg.cf = 4745.361328125; - test_msg.cp = 794.0; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 18; - test_msg.snr = 35.77723693847656; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 4745.36132812 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 4745.36132812, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 794.0 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 794.0, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 18) - << "incorrect value for last_msg_.sid.sat, expected 18, is " - << last_msg_.sid.sat; - EXPECT_LT((last_msg_.snr * 100 - 35.7772369385 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 35.7772369385, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepB3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepB3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepB3, Test) { - uint8_t encoded_frame[] = { - 85, 20, 0, 246, 215, 16, 46, 199, 14, 66, 0, 64, - 129, 67, 240, 24, 28, 69, 17, 0, 0, 0, 18, 181, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_acq_result_dep_b_t test_msg{}; - test_msg.cf = 2497.55859375; - test_msg.cp = 258.5; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 17; - test_msg.snr = 35.69451141357422; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 2497.55859375 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 2497.55859375, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 258.5 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 258.5, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 17) - << "incorrect value for last_msg_.sid.sat, expected 17, is " - << last_msg_.sid.sat; - EXPECT_LT((last_msg_.snr * 100 - 35.6945114136 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 35.6945114136, is " - << last_msg_.snr; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepB4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepB4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepB4, Test) { - uint8_t encoded_frame[] = { - 85, 20, 0, 246, 215, 16, 194, 24, 14, 66, 0, 128, - 2, 68, 129, 193, 249, 195, 5, 0, 0, 0, 35, 203, - }; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_B"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - sbp_msg_acq_result_dep_b_t test_msg{}; - test_msg.cf = -499.5117492675781; - test_msg.cp = 522.0; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 5; - test_msg.snr = 35.52417755126953; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -499.511749268 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -499.511749268, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cp * 100 - 522.0 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 522.0, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 5) - << "incorrect value for last_msg_.sid.sat, expected 5, is " - << last_msg_.sid.sat; - EXPECT_LT((last_msg_.snr * 100 - 35.5241775513 * 100), 0.05) - << "incorrect value for last_msg_.snr, expected 35.5241775513, is " - << last_msg_.snr; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepB2 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepB2() { + assign(test_msg_.cf, 4745.361328125); + assign(test_msg_.cp, 794.0); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 18); + assign(test_msg_.snr, 35.77723693847656); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_b, + sizeof(msg->acq_result_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x9bb3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_b_t &lesser, + const sbp_msg_acq_result_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_b_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 20, 0, 246, 215, 16, 228, 27, 15, 66, 0, 128, + 70, 68, 228, 74, 148, 69, 18, 0, 0, 0, 179, 155, + }; + uint8_t encoded_payload_[16] = { + 228, 27, 15, 66, 0, 128, 70, 68, 228, 74, 148, 69, 18, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_B"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepB3 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepB3() { + assign(test_msg_.cf, 2497.55859375); + assign(test_msg_.cp, 258.5); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 17); + assign(test_msg_.snr, 35.69451141357422); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_b, + sizeof(msg->acq_result_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xb512; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_b_t &lesser, + const sbp_msg_acq_result_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_b_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 20, 0, 246, 215, 16, 46, 199, 14, 66, 0, 64, + 129, 67, 240, 24, 28, 69, 17, 0, 0, 0, 18, 181, + }; + uint8_t encoded_payload_[16] = { + 46, 199, 14, 66, 0, 64, 129, 67, 240, 24, 28, 69, 17, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_B"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepB4 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepB4() { + assign(test_msg_.cf, -499.5117492675781); + assign(test_msg_.cp, 522.0); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 5); + assign(test_msg_.snr, 35.52417755126953); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_b, + sizeof(msg->acq_result_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xcb23; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_b_t &lesser, + const sbp_msg_acq_result_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_b_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 20, 0, 246, 215, 16, 194, 24, 14, 66, 0, 128, + 2, 68, 129, 193, 249, 195, 5, 0, 0, 0, 35, 203, + }; + uint8_t encoded_payload_[16] = { + 194, 24, 14, 66, 0, 128, 2, 68, 129, 193, 249, 195, 5, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_b_t lesser = info.test_msg; + sbp_msg_acq_result_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.snr, greater.snr); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_B"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepB4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepC.cc b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepC.cc index b78988b1dd..b48188f0fd 100644 --- a/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepC.cc +++ b/c/test/cpp/auto_check_sbp_acquisition_MsgAcqResultDepC.cc @@ -16,506 +16,3029 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_acquisition_MsgAcqResultDepC0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_acquisition_MsgAcqResultDepC0 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepC0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepC0() { + assign(test_msg_.cf, 1769.06591796875); + assign(test_msg_.cn0, 40.509063720703125); + assign(test_msg_.cp, 457.1922302246094); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 10); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepC, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_c, + sizeof(msg->acq_result_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_c, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepC); + info.sender_id = 3112; + info.preamble = 0x55; + info.crc = 0xbd09; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_c_t &lesser, + const sbp_msg_acq_result_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepC0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_c_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 31, 0, 40, 12, 16, 72, 9, 34, 66, 155, 152, 228, 67, 28, 34, 221, 68, 10, 0, 0, 0, 9, 189, }; + uint8_t encoded_payload_[16] = { + 72, 9, 34, 66, 155, 152, 228, 67, 28, 34, 221, 68, 10, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_c_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepC, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepC); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_C"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); - sbp_msg_acq_result_dep_c_t test_msg{}; - test_msg.cf = 1769.06591796875; - test_msg.cn0 = 40.509063720703125; - test_msg.cp = 457.1922302246094; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 10; - - EXPECT_EQ(send_message(3112, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 3112); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 1769.06591797 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 1769.06591797, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cn0 * 100 - 40.5090637207 * 100), 0.05) - << "incorrect value for last_msg_.cn0, expected 40.5090637207, is " - << last_msg_.cn0; - EXPECT_LT((last_msg_.cp * 100 - 457.192230225 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 457.192230225, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 10) - << "incorrect value for last_msg_.sid.sat, expected 10, is " - << last_msg_.sid.sat; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepC1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepC, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepC, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepC1 + : public ::testing::Test { public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepC1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_acquisition_MsgAcqResultDepC1() { + assign(test_msg_.cf, -505.4473876953125); + assign(test_msg_.cn0, 43.49464416503906); + assign(test_msg_.cp, 865.4657592773438); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 6); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepC, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_c, + sizeof(msg->acq_result_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_c, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepC); + info.sender_id = 3112; + info.preamble = 0x55; + info.crc = 0xb988; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acq_result_dep_c_t &lesser, + const sbp_msg_acq_result_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepC1, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_c_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 31, 0, 40, 12, 16, 132, 250, 45, 66, 207, 93, 88, 68, 68, 185, 252, 195, 6, 0, 0, 0, 136, 185, }; + uint8_t encoded_payload_[16] = { + 132, 250, 45, 66, 207, 93, 88, 68, 68, 185, 252, 195, 6, 0, 0, 0, + }; +}; - sbp_msg_acq_result_dep_c_t test_msg{}; - test_msg.cf = -505.4473876953125; - test_msg.cn0 = 43.49464416503906; - test_msg.cp = 865.4657592773438; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 6; - - EXPECT_EQ(send_message(3112, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 3112); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -505.447387695 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -505.447387695, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cn0 * 100 - 43.494644165 * 100), 0.05) - << "incorrect value for last_msg_.cn0, expected 43.494644165, is " - << last_msg_.cn0; - EXPECT_LT((last_msg_.cp * 100 - 865.465759277 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 865.465759277, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 6) - << "incorrect value for last_msg_.sid.sat, expected 6, is " - << last_msg_.sid.sat; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepC2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepC2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_c_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepC, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepC2, Test) { - uint8_t encoded_frame[] = { - 85, 31, 0, 40, 12, 16, 163, 223, 24, 66, 64, 91, - 102, 67, 202, 243, 157, 196, 13, 0, 0, 0, 150, 161, - }; + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_acq_result_dep_c_t test_msg{}; - test_msg.cf = -1263.618408203125; - test_msg.cn0 = 38.2183952331543; - test_msg.cp = 230.3564453125; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 13; - - EXPECT_EQ(send_message(3112, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 3112); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - -1263.6184082 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected -1263.6184082, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cn0 * 100 - 38.2183952332 * 100), 0.05) - << "incorrect value for last_msg_.cn0, expected 38.2183952332, is " - << last_msg_.cn0; - EXPECT_LT((last_msg_.cp * 100 - 230.356445312 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 230.356445312, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 13) - << "incorrect value for last_msg_.sid.sat, expected 13, is " - << last_msg_.sid.sat; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepC3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepC3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepC3, Test) { - uint8_t encoded_frame[] = { - 85, 31, 0, 40, 12, 16, 129, 65, 21, 66, 224, 214, - 124, 67, 243, 138, 61, 69, 1, 0, 0, 0, 109, 209, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_acq_result_dep_c_t test_msg{}; - test_msg.cf = 3032.684326171875; - test_msg.cn0 = 37.313968658447266; - test_msg.cp = 252.83935546875; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 1; - - EXPECT_EQ(send_message(3112, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 3112); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 3032.68432617 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 3032.68432617, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cn0 * 100 - 37.3139686584 * 100), 0.05) - << "incorrect value for last_msg_.cn0, expected 37.3139686584, is " - << last_msg_.cn0; - EXPECT_LT((last_msg_.cp * 100 - 252.839355469 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 252.839355469, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 1) - << "incorrect value for last_msg_.sid.sat, expected 1, is " - << last_msg_.sid.sat; -} -class Test_auto_check_sbp_acquisition_MsgAcqResultDepC4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_acquisition_MsgAcqResultDepC4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acq_result_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acq_result_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_acquisition_MsgAcqResultDepC4, Test) { - uint8_t encoded_frame[] = { - 85, 31, 0, 40, 12, 16, 126, 35, 62, 66, 226, 37, - 102, 68, 202, 243, 29, 69, 27, 0, 0, 0, 91, 67, - }; +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepC); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_C"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - sbp_msg_acq_result_dep_c_t test_msg{}; - test_msg.cf = 2527.23681640625; - test_msg.cn0 = 47.53466033935547; - test_msg.cp = 920.5919189453125; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 27; - - EXPECT_EQ(send_message(3112, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 3112); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cf * 100 - 2527.23681641 * 100), 0.05) - << "incorrect value for last_msg_.cf, expected 2527.23681641, is " - << last_msg_.cf; - EXPECT_LT((last_msg_.cn0 * 100 - 47.5346603394 * 100), 0.05) - << "incorrect value for last_msg_.cn0, expected 47.5346603394, is " - << last_msg_.cn0; - EXPECT_LT((last_msg_.cp * 100 - 920.591918945 * 100), 0.05) - << "incorrect value for last_msg_.cp, expected 920.591918945, is " - << last_msg_.cp; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 27) - << "incorrect value for last_msg_.sid.sat, expected 27, is " - << last_msg_.sid.sat; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepC, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepC, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepC2 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepC2() { + assign(test_msg_.cf, -1263.618408203125); + assign(test_msg_.cn0, 38.2183952331543); + assign(test_msg_.cp, 230.3564453125); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 13); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepC, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_c, + sizeof(msg->acq_result_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_c, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepC); + info.sender_id = 3112; + info.preamble = 0x55; + info.crc = 0xa196; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_c_t &lesser, + const sbp_msg_acq_result_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_c_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 31, 0, 40, 12, 16, 163, 223, 24, 66, 64, 91, + 102, 67, 202, 243, 157, 196, 13, 0, 0, 0, 150, 161, + }; + uint8_t encoded_payload_[16] = { + 163, 223, 24, 66, 64, 91, 102, 67, 202, 243, 157, 196, 13, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_c_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepC, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepC); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_C"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepC, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepC, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepC3 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepC3() { + assign(test_msg_.cf, 3032.684326171875); + assign(test_msg_.cn0, 37.313968658447266); + assign(test_msg_.cp, 252.83935546875); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepC, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_c, + sizeof(msg->acq_result_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_c, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepC); + info.sender_id = 3112; + info.preamble = 0x55; + info.crc = 0xd16d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_c_t &lesser, + const sbp_msg_acq_result_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_c_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 31, 0, 40, 12, 16, 129, 65, 21, 66, 224, 214, + 124, 67, 243, 138, 61, 69, 1, 0, 0, 0, 109, 209, + }; + uint8_t encoded_payload_[16] = { + 129, 65, 21, 66, 224, 214, 124, 67, 243, 138, 61, 69, 1, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_c_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepC, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepC); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_C"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepC, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepC, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_acquisition_MsgAcqResultDepC4 + : public ::testing::Test { + public: + Testauto_check_sbp_acquisition_MsgAcqResultDepC4() { + assign(test_msg_.cf, 2527.23681640625); + assign(test_msg_.cn0, 47.53466033935547); + assign(test_msg_.cp, 920.5919189453125); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 27); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acq_result_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcqResultDepC, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acq_result_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcqResultDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acq_result_dep_c, + sizeof(msg->acq_result_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acq_result_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acq_result_dep_c, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcqResultDepC); + info.sender_id = 3112; + info.preamble = 0x55; + info.crc = 0x435b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_acq_result_dep_c_t &lesser, + const sbp_msg_acq_result_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acq_result_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acq_result_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acq_result_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcqResultDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_acq_result_dep_c_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { + 85, 31, 0, 40, 12, 16, 126, 35, 62, 66, 226, 37, + 102, 68, 202, 243, 29, 69, 27, 0, 0, 0, 91, 67, + }; + uint8_t encoded_payload_[16] = { + 126, 35, 62, 66, 226, 37, 102, 68, 202, 243, 29, 69, 27, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acq_result_dep_c_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAcqResultDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcqResultDepC, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ( + sbp_msg_acq_result_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcqResultDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_acq_result_dep_c_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acq_result_dep_c_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcqResultDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cf, greater.cf); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.cp, greater.cp); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_acq_result_dep_c_t lesser = info.test_msg; + sbp_msg_acq_result_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcqResultDepC); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACQ_RESULT_DEP_C"); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acq_result_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acq_result_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acq_result_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.acq_result_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acq_result_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcqResultDepC, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_acquisition_MsgAcqResultDepC4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcqResultDepC, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_bootload_MsgBootloaderHandshakeResp.cc b/c/test/cpp/auto_check_sbp_bootload_MsgBootloaderHandshakeResp.cc index 011184a04f..cb0ef436ff 100644 --- a/c/test/cpp/auto_check_sbp_bootload_MsgBootloaderHandshakeResp.cc +++ b/c/test/cpp/auto_check_sbp_bootload_MsgBootloaderHandshakeResp.cc @@ -16,185 +16,1508 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0 + : public ::testing::Test { public: - Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0() { + assign(test_msg_.flags, 0); + + size_t written; + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set( + &test_msg_, "v1.2\n", false, &written)); + EXPECT_EQ(written, strlen("v1.2\n")); + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_version_encoded_len(&test_msg_), + 5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_bootloader_handshake_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_bootloader_handshake_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_bootloader_handshake_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBootloaderHandshakeResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_bootloader_handshake_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBootloaderHandshakeResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->bootloader_handshake_resp, + sizeof(msg->bootloader_handshake_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_bootloader_handshake_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.bootloader_handshake_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBootloaderHandshakeResp); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0x1c9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 9; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_bootloader_handshake_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_bootloader_handshake_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_bootloader_handshake_resp_t &lesser, + const sbp_msg_bootloader_handshake_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_bootloader_handshake_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_bootloader_handshake_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBootloaderHandshakeResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBootloaderHandshakeResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBootloaderHandshakeResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBootloaderHandshakeResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); -TEST_F(Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp0, Test) { - uint8_t encoded_frame[] = { + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_bootloader_handshake_resp_t test_msg_{}; + uint8_t encoded_frame_[9 + 8] = { 85, 180, 0, 0, 0, 9, 0, 0, 0, 0, 118, 49, 46, 50, 10, 201, 1, }; + uint8_t encoded_payload_[9] = { + 0, 0, 0, 0, 118, 49, 46, 50, 10, + }; +}; + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBootloaderHandshakeResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBootloaderHandshakeResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + for (uint8_t i = 0; i < 9; i++) { + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgBootloaderHandshakeResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_resp_t msg{}; + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_BOOTLOADER_HANDSHAKE_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_bootloader_handshake_resp_t t{}; + // return sbp_msg_bootloader_handshake_resp_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_bootloader_handshake_resp_t test_msg{}; - test_msg.flags = 0; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgBootloaderHandshakeResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_bootloader_handshake_resp_t lesser = info.test_msg; + sbp_msg_bootloader_handshake_resp_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_bootloader_handshake_resp_t lesser = info.test_msg; + sbp_msg_bootloader_handshake_resp_t greater = info.test_msg; + make_lesser_greater(lesser.version, greater.version); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBootloaderHandshakeResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BOOTLOADER_HANDSHAKE_RESP"); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_bootloader_handshake_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_bootloader_handshake_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.bootloader_handshake_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.bootloader_handshake_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBootloaderHandshakeResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBootloaderHandshakeResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version + : public Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0 {}; + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + StringInit) { + sbp_msg_bootloader_handshake_resp_t t{}; + sbp_msg_bootloader_handshake_resp_version_init(&t); + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_valid(&t)); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + IsValid) { + sbp_msg_bootloader_handshake_resp_t t{}; size_t written; - EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set(&test_msg, "v1.2\n", - false, &written)); + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set(&t, "v1.2\n", false, + &written)); EXPECT_EQ(written, strlen("v1.2\n")); - EXPECT_EQ(sbp_msg_bootloader_handshake_resp_version_encoded_len(&test_msg), - 5); + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_version_encoded_len(&t), 5); + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_valid(&t)); +} - EXPECT_EQ(send_message(0, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + SpaceRemaining) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_bootloader_handshake_resp_version_space_remaining(&t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + size_t written; + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set(&t, "v1.2\n", false, + &written)); + EXPECT_EQ(written, strlen("v1.2\n")); + EXPECT_EQ(sbp_msg_bootloader_handshake_resp_version_encoded_len(&t), 5); + size_t assigned_space_remaining = + sbp_msg_bootloader_handshake_resp_version_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_resp_t t{}; + + size_t nwritten{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set_raw( + &t, info.test_msg.version.data, + sbp_msg_bootloader_handshake_resp_version_strlen(&info.test_msg), false, + &nwritten)); + EXPECT_EQ( + sbp_msg_bootloader_handshake_resp_version_encoded_len(&info.test_msg), + sbp_msg_bootloader_handshake_resp_version_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, Set) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t nwritten{}; + const char *text = "v1.2\n"; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_set(&t, text, false, + &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), text); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + Printf) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t nwritten{}; + const char *text = "v1.2\n"; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_printf( + &t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), text); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + Vprintf) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t nwritten{}; + const char *text = "v1.2\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_bootloader_handshake_resp_version_vprintf( + &t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; - EXPECT_EQ(sbp_msg_bootloader_handshake_resp_version_encoded_len(&last_msg_), - 5); - EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&last_msg_), - "v1.2\n"); + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), text); } -class Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + AppendPrintf) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t nwritten{}; + char part1[] = "v1.2\n"; + char part2[] = "v1.2\n"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_printf( + &t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_append_printf( + &t, false, &nwritten, "%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), "v1.2\n"); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp0_version, + AppendVprintf) { + sbp_msg_bootloader_handshake_resp_t t{}; + size_t nwritten{}; + char part1[] = "v1.2\n"; + char part2[] = "v1.2\n"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_resp_version_printf( + &t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_bootloader_handshake_resp_version_append_vprintf( + &t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_bootloader_handshake_resp_version_get(&t), "v1.2\n"); +} + +class Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1 + : public ::testing::Test { public: - Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1() { + size_t written; + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_set( + &test_msg_, "v1.2", false, &written)); + EXPECT_EQ(written, strlen("v1.2")); + EXPECT_EQ( + sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&test_msg_), + 4); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_bootloader_handshake_dep_a_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_bootloader_handshake_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_bootloader_handshake_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBootloaderHandshakeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_bootloader_handshake_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBootloaderHandshakeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->bootloader_handshake_dep_a, + sizeof(msg->bootloader_handshake_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_bootloader_handshake_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.bootloader_handshake_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBootloaderHandshakeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xce01; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_bootloader_handshake_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_bootloader_handshake_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_bootloader_handshake_dep_a_t &lesser, + const sbp_msg_bootloader_handshake_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_bootloader_handshake_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_bootloader_handshake_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBootloaderHandshakeDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBootloaderHandshakeDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBootloaderHandshakeDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBootloaderHandshakeDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_bootload_MsgBootloaderHandshakeResp1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_bootloader_handshake_dep_a_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 176, 0, 195, 4, 4, 118, 49, 46, 50, 1, 206, }; + uint8_t encoded_payload_[4] = { + 118, + 49, + 46, + 50, + }; +}; + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBootloaderHandshakeDepA, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBootloaderHandshakeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgBootloaderHandshakeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_BOOTLOADER_HANDSHAKE_DEP_A_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_bootloader_handshake_dep_a_t t{}; + // return sbp_msg_bootloader_handshake_dep_a_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - sbp_msg_bootloader_handshake_dep_a_t test_msg{}; +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgBootloaderHandshakeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_bootloader_handshake_dep_a_t lesser = info.test_msg; + sbp_msg_bootloader_handshake_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.handshake, greater.handshake); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBootloaderHandshakeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BOOTLOADER_HANDSHAKE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_bootloader_handshake_dep_a_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_bootloader_handshake_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.bootloader_handshake_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.bootloader_handshake_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBootloaderHandshakeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBootloaderHandshakeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake + : public Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1 {}; + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + StringInit) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + sbp_msg_bootloader_handshake_dep_a_handshake_init(&t); + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_valid(&t)); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + IsValid) { + sbp_msg_bootloader_handshake_dep_a_t t{}; size_t written; EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_set( - &test_msg, "v1.2", false, &written)); + &t, "v1.2", false, &written)); EXPECT_EQ(written, strlen("v1.2")); - EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&test_msg), - 4); + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&t), 4); + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_valid(&t)); +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + SpaceRemaining) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t empty_space_remaining = + sbp_msg_bootloader_handshake_dep_a_handshake_space_remaining(&t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + size_t written; + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_set( + &t, "v1.2", false, &written)); + EXPECT_EQ(written, strlen("v1.2")); + EXPECT_EQ(sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&t), 4); + size_t assigned_space_remaining = + sbp_msg_bootloader_handshake_dep_a_handshake_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_bootloader_handshake_dep_a_t t{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); + size_t nwritten{}; + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_set_raw( + &t, info.test_msg.handshake.data, + sbp_msg_bootloader_handshake_dep_a_handshake_strlen(&info.test_msg), + false, &nwritten)); EXPECT_EQ( - sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&last_msg_), 4); - EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&last_msg_), - "v1.2"); + sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&info.test_msg), + sbp_msg_bootloader_handshake_dep_a_handshake_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, Set) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t nwritten{}; + const char *text = "v1.2"; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_set(&t, text, false, + &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), text); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + Printf) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t nwritten{}; + const char *text = "v1.2"; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_printf( + &t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), text); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + Vprintf) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t nwritten{}; + const char *text = "v1.2"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_bootloader_handshake_dep_a_handshake_vprintf( + &t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), text); +} + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + AppendPrintf) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t nwritten{}; + char part1[] = "v1.2"; + char part2[] = "v1.2"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_printf( + &t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_append_printf( + &t, false, &nwritten, "%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), "v1.2"); } + +TEST_F(Testauto_check_sbp_bootload_MsgBootloaderHandshakeResp1_handshake, + AppendVprintf) { + sbp_msg_bootloader_handshake_dep_a_t t{}; + size_t nwritten{}; + char part1[] = "v1.2"; + char part2[] = "v1.2"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_bootloader_handshake_dep_a_handshake_printf( + &t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_bootloader_handshake_dep_a_handshake_append_vprintf( + &t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_bootloader_handshake_dep_a_handshake_get(&t), "v1.2"); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ext_events_MsgExtEvent.cc b/c/test/cpp/auto_check_sbp_ext_events_MsgExtEvent.cc index 4aa13a8542..9cda77bc25 100644 --- a/c/test/cpp/auto_check_sbp_ext_events_MsgExtEvent.cc +++ b/c/test/cpp/auto_check_sbp_ext_events_MsgExtEvent.cc @@ -16,100 +16,587 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ext_events_MsgExtEvent0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ext_events_MsgExtEvent0 : public ::testing::Test { public: - Test_auto_check_sbp_ext_events_MsgExtEvent0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ext_events_MsgExtEvent0() { + assign(test_msg_.flags, 3); + assign(test_msg_.ns_residual, 999882); + assign(test_msg_.pin, 0); + assign(test_msg_.tow, 254924999); + assign(test_msg_.wn, 1840); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ext_event_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ext_event_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgExtEvent, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ext_event_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgExtEvent); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ext_event, sizeof(msg->ext_event)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ext_event_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ext_event, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgExtEvent); + info.sender_id = 1781; + info.preamble = 0x55; + info.crc = 0xcc3e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 12; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ext_event_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ext_event_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ext_event_t &lesser, + const sbp_msg_ext_event_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ext_event_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ext_event_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ext_event_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ext_event_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgExtEvent, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgExtEvent, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgExtEvent, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgExtEvent, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_ext_events_MsgExtEvent0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ext_event_t test_msg_{}; + uint8_t encoded_frame_[12 + 8] = { 85, 1, 1, 245, 6, 12, 48, 7, 199, 216, 49, 15, 202, 65, 15, 0, 3, 0, 62, 204, }; + uint8_t encoded_payload_[12] = { + 48, 7, 199, 216, 49, 15, 202, 65, 15, 0, 3, 0, + }; +}; + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ext_event_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgExtEvent, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[12]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ext_event_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 12); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 12), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgExtEvent, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 12); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 12), 0); +} - sbp_msg_ext_event_t test_msg{}; - test_msg.flags = 3; - test_msg.ns_residual = 999882; - test_msg.pin = 0; - test_msg.tow = 254924999; - test_msg.wn = 1840; - - EXPECT_EQ(send_message(1781, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1781); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 3) - << "incorrect value for last_msg_.flags, expected 3, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 999882) - << "incorrect value for last_msg_.ns_residual, expected 999882, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.pin, 0) - << "incorrect value for last_msg_.pin, expected 0, is " << last_msg_.pin; - EXPECT_EQ(last_msg_.tow, 254924999) - << "incorrect value for last_msg_.tow, expected 254924999, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1840) - << "incorrect value for last_msg_.wn, expected 1840, is " << last_msg_.wn; +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[12]; + + EXPECT_EQ( + sbp_msg_ext_event_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 12), 0); } +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[12]; + + for (uint8_t i = 0; i < 12; i++) { + EXPECT_EQ(sbp_msg_ext_event_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ext_event_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ext_event_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 12); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgExtEvent, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 12); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ext_event_t msg{}; + + EXPECT_EQ(sbp_msg_ext_event_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ext_event_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_ext_event_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ext_event_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgExtEvent, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ext_event_t lesser = info.test_msg; + sbp_msg_ext_event_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_ext_event_t lesser = info.test_msg; + sbp_msg_ext_event_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_ext_event_t lesser = info.test_msg; + sbp_msg_ext_event_t greater = info.test_msg; + make_lesser_greater(lesser.pin, greater.pin); + comparison_tests(lesser, greater); + } + { + sbp_msg_ext_event_t lesser = info.test_msg; + sbp_msg_ext_event_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ext_event_t lesser = info.test_msg; + sbp_msg_ext_event_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgExtEvent); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_EXT_EVENT"); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ext_event_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ext_event_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ext_event, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ext_event, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[12]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 12); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 12), 0); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ext_event_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 12); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgExtEvent, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ext_events_MsgExtEvent0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgExtEvent, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_file_io_MsgFileioWriteResp.cc b/c/test/cpp/auto_check_sbp_file_io_MsgFileioWriteResp.cc index 5c28ff7902..3bba183b08 100644 --- a/c/test/cpp/auto_check_sbp_file_io_MsgFileioWriteResp.cc +++ b/c/test/cpp/auto_check_sbp_file_io_MsgFileioWriteResp.cc @@ -16,85 +16,579 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_file_io_MsgFileioWriteResp0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_file_io_MsgFileioWriteResp0 : public ::testing::Test { public: - Test_auto_check_sbp_file_io_MsgFileioWriteResp0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_file_io_MsgFileioWriteResp0() { + assign(test_msg_.sequence, 202); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_fileio_write_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_fileio_write_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgFileioWriteResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_fileio_write_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgFileioWriteResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->fileio_write_resp, + sizeof(msg->fileio_write_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_fileio_write_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.fileio_write_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgFileioWriteResp); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xf3f3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_fileio_write_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_fileio_write_resp_t &lesser, + const sbp_msg_fileio_write_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_fileio_write_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_fileio_write_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_fileio_write_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_fileio_write_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgFileioWriteResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgFileioWriteResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgFileioWriteResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgFileioWriteResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_fileio_write_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_file_io_MsgFileioWriteResp0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_fileio_write_resp_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 171, 0, 66, 0, 4, 202, 0, 0, 0, 243, 243, }; + uint8_t encoded_payload_[4] = { + 202, + 0, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_fileio_write_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgFileioWriteResp, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_fileio_write_resp_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgFileioWriteResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ(sbp_msg_fileio_write_resp_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ( + sbp_msg_fileio_write_resp_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} - sbp_msg_fileio_write_resp_t test_msg{}; - test_msg.sequence = 202; +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_fileio_write_resp_t msg{}; + uint8_t n_read; - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_fileio_write_resp_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgFileioWriteResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_fileio_write_resp_t msg{}; + + EXPECT_EQ(sbp_msg_fileio_write_resp_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_fileio_write_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ(sbp_msg_fileio_write_resp_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_fileio_write_resp_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgFileioWriteResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_fileio_write_resp_t lesser = info.test_msg; + sbp_msg_fileio_write_resp_t greater = info.test_msg; + make_lesser_greater(lesser.sequence, greater.sequence); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgFileioWriteResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_FILEIO_WRITE_RESP"); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_fileio_write_resp_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_fileio_write_resp_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.fileio_write_resp, info.test_msg); - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.sequence, 202) - << "incorrect value for last_msg_.sequence, expected 202, is " - << last_msg_.sequence; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.fileio_write_resp, info.test_msg); } + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_fileio_write_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgFileioWriteResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_file_io_MsgFileioWriteResp0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgFileioWriteResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_imu_MsgImuAux.cc b/c/test/cpp/auto_check_sbp_imu_MsgImuAux.cc index 1a364b74f3..617c6da27c 100644 --- a/c/test/cpp/auto_check_sbp_imu_MsgImuAux.cc +++ b/c/test/cpp/auto_check_sbp_imu_MsgImuAux.cc @@ -16,93 +16,571 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_imu_MsgImuAux0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_imu_MsgImuAux0 : public ::testing::Test { public: - Test_auto_check_sbp_imu_MsgImuAux0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_imu_MsgImuAux0() { + assign(test_msg_.imu_conf, 66); + assign(test_msg_.imu_type, 1); + assign(test_msg_.temp, 2804); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_imu_aux_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_imu_aux_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgImuAux, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_imu_aux_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgImuAux); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->imu_aux, sizeof(msg->imu_aux)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_imu_aux_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.imu_aux, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgImuAux); + info.sender_id = 4660; + info.preamble = 0x55; + info.crc = 0xfcc8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_imu_aux_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_imu_aux_t &lesser, + const sbp_msg_imu_aux_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_imu_aux_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_imu_aux_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_imu_aux_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_imu_aux_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgImuAux, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgImuAux, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgImuAux, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgImuAux, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_imu_aux_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_imu_MsgImuAux0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_imu_aux_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 1, 9, 52, 18, 4, 1, 244, 10, 66, 200, 252, }; + uint8_t encoded_payload_[4] = { + 1, + 244, + 10, + 66, + }; +}; + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_imu_aux_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgImuAux, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_imu_aux_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgImuAux, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_imu_aux_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_imu_aux_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_imu_aux_t msg{}; + uint8_t n_read; - sbp_msg_imu_aux_t test_msg{}; - test_msg.imu_conf = 66; - test_msg.imu_type = 1; - test_msg.temp = 2804; + EXPECT_EQ(sbp_msg_imu_aux_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(send_message(4660, test_msg), SBP_OK); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgImuAux, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_imu_aux_t msg{}; + + EXPECT_EQ(sbp_msg_imu_aux_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_imu_aux_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_imu_aux_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_imu_aux_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgImuAux, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_imu_aux_t lesser = info.test_msg; + sbp_msg_imu_aux_t greater = info.test_msg; + make_lesser_greater(lesser.imu_conf, greater.imu_conf); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_aux_t lesser = info.test_msg; + sbp_msg_imu_aux_t greater = info.test_msg; + make_lesser_greater(lesser.imu_type, greater.imu_type); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_aux_t lesser = info.test_msg; + sbp_msg_imu_aux_t greater = info.test_msg; + make_lesser_greater(lesser.temp, greater.temp); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgImuAux); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IMU_AUX"); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_imu_aux_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_imu_aux_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.imu_aux, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.imu_aux, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_imu_aux_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4660); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.imu_conf, 66) - << "incorrect value for last_msg_.imu_conf, expected 66, is " - << last_msg_.imu_conf; - EXPECT_EQ(last_msg_.imu_type, 1) - << "incorrect value for last_msg_.imu_type, expected 1, is " - << last_msg_.imu_type; - EXPECT_EQ(last_msg_.temp, 2804) - << "incorrect value for last_msg_.temp, expected 2804, is " - << last_msg_.temp; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgImuAux, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuAux0, SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgImuAux, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_imu_MsgImuRaw.cc b/c/test/cpp/auto_check_sbp_imu_MsgImuRaw.cc index aba8b748ca..505f6d1341 100644 --- a/c/test/cpp/auto_check_sbp_imu_MsgImuRaw.cc +++ b/c/test/cpp/auto_check_sbp_imu_MsgImuRaw.cc @@ -16,114 +16,604 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_imu_MsgImuRaw0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_imu_MsgImuRaw0 : public ::testing::Test { public: - Test_auto_check_sbp_imu_MsgImuRaw0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_imu_MsgImuRaw0() { + assign(test_msg_.acc_x, 96); + assign(test_msg_.acc_y, -33); + assign(test_msg_.acc_z, 4140); + assign(test_msg_.gyr_x, 60); + assign(test_msg_.gyr_y, -304); + assign(test_msg_.gyr_z, -18); + assign(test_msg_.tow, 3221225754); + assign(test_msg_.tow_f, 206); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_imu_raw_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_imu_raw_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgImuRaw, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_imu_raw_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgImuRaw); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->imu_raw, sizeof(msg->imu_raw)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_imu_raw_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.imu_raw, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgImuRaw); + info.sender_id = 4660; + info.preamble = 0x55; + info.crc = 0x8746; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 17; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_imu_raw_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_imu_raw_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_imu_raw_t &lesser, + const sbp_msg_imu_raw_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_imu_raw_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_imu_raw_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_imu_raw_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_imu_raw_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgImuRaw, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgImuRaw, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgImuRaw, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgImuRaw, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_imu_MsgImuRaw0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_imu_raw_t test_msg_{}; + uint8_t encoded_frame_[17 + 8] = { 85, 0, 9, 52, 18, 17, 26, 1, 0, 192, 206, 96, 0, 223, 255, 44, 16, 60, 0, 208, 254, 238, 255, 70, 135, }; + uint8_t encoded_payload_[17] = { + 26, 1, 0, 192, 206, 96, 0, 223, 255, 44, 16, 60, 0, 208, 254, 238, 255, + }; +}; + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_imu_raw_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgImuRaw, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_imu_raw_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgImuRaw, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + EXPECT_EQ( + sbp_msg_imu_raw_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + for (uint8_t i = 0; i < 17; i++) { + EXPECT_EQ(sbp_msg_imu_raw_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_imu_raw_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_imu_raw_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgImuRaw, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_imu_raw_t test_msg{}; - test_msg.acc_x = 96; - test_msg.acc_y = -33; - test_msg.acc_z = 4140; - test_msg.gyr_x = 60; - test_msg.gyr_y = -304; - test_msg.gyr_z = -18; - test_msg.tow = 3221225754; - test_msg.tow_f = 206; - - EXPECT_EQ(send_message(4660, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4660); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.acc_x, 96) - << "incorrect value for last_msg_.acc_x, expected 96, is " - << last_msg_.acc_x; - EXPECT_EQ(last_msg_.acc_y, -33) - << "incorrect value for last_msg_.acc_y, expected -33, is " - << last_msg_.acc_y; - EXPECT_EQ(last_msg_.acc_z, 4140) - << "incorrect value for last_msg_.acc_z, expected 4140, is " - << last_msg_.acc_z; - EXPECT_EQ(last_msg_.gyr_x, 60) - << "incorrect value for last_msg_.gyr_x, expected 60, is " - << last_msg_.gyr_x; - EXPECT_EQ(last_msg_.gyr_y, -304) - << "incorrect value for last_msg_.gyr_y, expected -304, is " - << last_msg_.gyr_y; - EXPECT_EQ(last_msg_.gyr_z, -18) - << "incorrect value for last_msg_.gyr_z, expected -18, is " - << last_msg_.gyr_z; - EXPECT_EQ(last_msg_.tow, 3221225754) - << "incorrect value for last_msg_.tow, expected 3221225754, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.tow_f, 206) - << "incorrect value for last_msg_.tow_f, expected 206, is " - << last_msg_.tow_f; +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_imu_raw_t msg{}; + + EXPECT_EQ(sbp_msg_imu_raw_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_imu_raw_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_imu_raw_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_imu_raw_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgImuRaw, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.acc_x, greater.acc_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.acc_y, greater.acc_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.acc_z, greater.acc_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.gyr_x, greater.gyr_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.gyr_y, greater.gyr_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.gyr_z, greater.gyr_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_imu_raw_t lesser = info.test_msg; + sbp_msg_imu_raw_t greater = info.test_msg; + make_lesser_greater(lesser.tow_f, greater.tow_f); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgImuRaw); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IMU_RAW"); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_imu_raw_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_imu_raw_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.imu_raw, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.imu_raw, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_imu_raw_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgImuRaw, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_imu_MsgImuRaw0, SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgImuRaw, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgAcknowledge.cc b/c/test/cpp/auto_check_sbp_integrity_MsgAcknowledge.cc index 3274f588e8..f8894d5682 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgAcknowledge.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgAcknowledge.cc @@ -16,106 +16,606 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgAcknowledge0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgAcknowledge0 : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgAcknowledge0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgAcknowledge0() { + assign(test_msg_.area_id, 123456); + assign(test_msg_.correction_mask_on_demand, 1); + assign(test_msg_.correction_mask_stream, 1); + assign(test_msg_.request_id, 30); + assign(test_msg_.response_code, 0); + assign(test_msg_.solution_id, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_acknowledge_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_acknowledge_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAcknowledge, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_acknowledge_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAcknowledge); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->acknowledge, sizeof(msg->acknowledge)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_acknowledge_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.acknowledge, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAcknowledge); + info.sender_id = 42; + info.preamble = 0x55; + info.crc = 0xB256; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_acknowledge_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_acknowledge_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_acknowledge_t &lesser, + const sbp_msg_acknowledge_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_acknowledge_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_acknowledge_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_acknowledge_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_acknowledge_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcknowledge, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgAcknowledge, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAcknowledge, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAcknowledge, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgAcknowledge0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_acknowledge_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 210, 11, 42, 0, 11, 30, 64, 226, 1, 0, 0, 1, 0, 1, 0, 2, 86, 178, }; + uint8_t encoded_payload_[11] = { + 30, 64, 226, 1, 0, 0, 1, 0, 1, 0, 2, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_acknowledge_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgAcknowledge, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_acknowledge_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAcknowledge, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_acknowledge_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_acknowledge_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acknowledge_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_acknowledge_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAcknowledge, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_acknowledge_t msg{}; + + EXPECT_EQ(sbp_msg_acknowledge_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_acknowledge_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_acknowledge_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_acknowledge_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAcknowledge, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.area_id, greater.area_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.correction_mask_on_demand, + greater.correction_mask_on_demand); + comparison_tests(lesser, greater); + } + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.correction_mask_stream, + greater.correction_mask_stream); + comparison_tests(lesser, greater); + } + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.request_id, greater.request_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.response_code, greater.response_code); + comparison_tests(lesser, greater); + } + { + sbp_msg_acknowledge_t lesser = info.test_msg; + sbp_msg_acknowledge_t greater = info.test_msg; + make_lesser_greater(lesser.solution_id, greater.solution_id); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAcknowledge); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ACKNOWLEDGE"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_acknowledge_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_acknowledge_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - sbp_msg_acknowledge_t test_msg{}; - test_msg.area_id = 123456; - test_msg.correction_mask_on_demand = 1; - test_msg.correction_mask_stream = 1; - test_msg.request_id = 30; - test_msg.response_code = 0; - test_msg.solution_id = 2; - - EXPECT_EQ(send_message(42, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 42); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.area_id, 123456) - << "incorrect value for last_msg_.area_id, expected 123456, is " - << last_msg_.area_id; - EXPECT_EQ(last_msg_.correction_mask_on_demand, 1) - << "incorrect value for last_msg_.correction_mask_on_demand, expected 1, " - "is " - << last_msg_.correction_mask_on_demand; - EXPECT_EQ(last_msg_.correction_mask_stream, 1) - << "incorrect value for last_msg_.correction_mask_stream, expected 1, is " - << last_msg_.correction_mask_stream; - EXPECT_EQ(last_msg_.request_id, 30) - << "incorrect value for last_msg_.request_id, expected 30, is " - << last_msg_.request_id; - EXPECT_EQ(last_msg_.response_code, 0) - << "incorrect value for last_msg_.response_code, expected 0, is " - << last_msg_.response_code; - EXPECT_EQ(last_msg_.solution_id, 2) - << "incorrect value for last_msg_.solution_id, expected 2, is " - << last_msg_.solution_id; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.acknowledge, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.acknowledge, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_acknowledge_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAcknowledge, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgAcknowledge0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAcknowledge, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagHighLevel.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagHighLevel.cc index 21dfbfe29c..b770e78c5e 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagHighLevel.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagHighLevel.cc @@ -16,173 +16,743 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagHighLevel0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagHighLevel0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0() { + assign(test_msg_.chain_id, 40); + assign(test_msg_.corr_time.tow, 360); + assign(test_msg_.corr_time.wn, 6); + assign(test_msg_.obs_time.tow, 180); + assign(test_msg_.obs_time.wn, 3); + + assign(test_msg_.reserved[0], 0); + + assign(test_msg_.reserved[1], 0); + + assign(test_msg_.reserved[2], 0); + + assign(test_msg_.reserved[3], 0); + + assign(test_msg_.reserved[4], 0); + + assign(test_msg_.reserved[5], 0); + assign(test_msg_.ssr_sol_id, 10); + assign(test_msg_.tile_id, 30); + assign(test_msg_.tile_set_id, 20); + assign(test_msg_.use_bds_sat, 3); + assign(test_msg_.use_gal_sat, 2); + assign(test_msg_.use_gps_sat, 1); + assign(test_msg_.use_iono_grid_point_sat_los, 7); + assign(test_msg_.use_iono_grid_points, 5); + assign(test_msg_.use_iono_tile_sat_los, 6); + assign(test_msg_.use_tropo_grid_points, 4); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_high_level_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_flag_high_level_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagHighLevel, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_high_level_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagHighLevel); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_high_level, + sizeof(msg->ssr_flag_high_level)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_high_level_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_high_level, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrFlagHighLevel); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x4366; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 31; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_flag_high_level_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_high_level_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_flag_high_level_t &lesser, + const sbp_msg_ssr_flag_high_level_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_flag_high_level_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_flag_high_level_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_flag_high_level_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagHighLevel, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagHighLevel, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagHighLevel, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagHighLevel, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagHighLevel0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_high_level_t test_msg_{}; + uint8_t encoded_frame_[31 + 8] = { 85, 185, 11, 66, 0, 31, 180, 0, 0, 0, 3, 0, 104, 1, 0, 0, 6, 0, 10, 20, 0, 30, 0, 40, 1, 2, 3, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, 102, 67, }; + uint8_t encoded_payload_[31] = { + 180, 0, 0, 0, 3, 0, 104, 1, 0, 0, 6, 0, 10, 20, 0, 30, + 0, 40, 1, 2, 3, 0, 0, 0, 0, 0, 0, 4, 5, 6, 7, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_flag_high_level_encoded_len(&info.test_msg), + info.payload_len); - sbp_msg_ssr_flag_high_level_t test_msg{}; - test_msg.chain_id = 40; - test_msg.corr_time.tow = 360; - test_msg.corr_time.wn = 6; - test_msg.obs_time.tow = 180; - test_msg.obs_time.wn = 3; - - test_msg.reserved[0] = 0; - - test_msg.reserved[1] = 0; - - test_msg.reserved[2] = 0; - - test_msg.reserved[3] = 0; - - test_msg.reserved[4] = 0; - - test_msg.reserved[5] = 0; - test_msg.ssr_sol_id = 10; - test_msg.tile_id = 30; - test_msg.tile_set_id = 20; - test_msg.use_bds_sat = 3; - test_msg.use_gal_sat = 2; - test_msg.use_gps_sat = 1; - test_msg.use_iono_grid_point_sat_los = 7; - test_msg.use_iono_grid_points = 5; - test_msg.use_iono_tile_sat_los = 6; - test_msg.use_tropo_grid_points = 4; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.chain_id, 40) - << "incorrect value for last_msg_.chain_id, expected 40, is " - << last_msg_.chain_id; - EXPECT_EQ(last_msg_.corr_time.tow, 360) - << "incorrect value for last_msg_.corr_time.tow, expected 360, is " - << last_msg_.corr_time.tow; - EXPECT_EQ(last_msg_.corr_time.wn, 6) - << "incorrect value for last_msg_.corr_time.wn, expected 6, is " - << last_msg_.corr_time.wn; - EXPECT_EQ(last_msg_.obs_time.tow, 180) - << "incorrect value for last_msg_.obs_time.tow, expected 180, is " - << last_msg_.obs_time.tow; - EXPECT_EQ(last_msg_.obs_time.wn, 3) - << "incorrect value for last_msg_.obs_time.wn, expected 3, is " - << last_msg_.obs_time.wn; - EXPECT_EQ(last_msg_.reserved[0], 0) - << "incorrect value for last_msg_.reserved[0], expected 0, is " - << last_msg_.reserved[0]; - EXPECT_EQ(last_msg_.reserved[1], 0) - << "incorrect value for last_msg_.reserved[1], expected 0, is " - << last_msg_.reserved[1]; - EXPECT_EQ(last_msg_.reserved[2], 0) - << "incorrect value for last_msg_.reserved[2], expected 0, is " - << last_msg_.reserved[2]; - EXPECT_EQ(last_msg_.reserved[3], 0) - << "incorrect value for last_msg_.reserved[3], expected 0, is " - << last_msg_.reserved[3]; - EXPECT_EQ(last_msg_.reserved[4], 0) - << "incorrect value for last_msg_.reserved[4], expected 0, is " - << last_msg_.reserved[4]; - EXPECT_EQ(last_msg_.reserved[5], 0) - << "incorrect value for last_msg_.reserved[5], expected 0, is " - << last_msg_.reserved[5]; - EXPECT_EQ(last_msg_.ssr_sol_id, 10) - << "incorrect value for last_msg_.ssr_sol_id, expected 10, is " - << last_msg_.ssr_sol_id; - EXPECT_EQ(last_msg_.tile_id, 30) - << "incorrect value for last_msg_.tile_id, expected 30, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 20) - << "incorrect value for last_msg_.tile_set_id, expected 20, is " - << last_msg_.tile_set_id; - EXPECT_EQ(last_msg_.use_bds_sat, 3) - << "incorrect value for last_msg_.use_bds_sat, expected 3, is " - << last_msg_.use_bds_sat; - EXPECT_EQ(last_msg_.use_gal_sat, 2) - << "incorrect value for last_msg_.use_gal_sat, expected 2, is " - << last_msg_.use_gal_sat; - EXPECT_EQ(last_msg_.use_gps_sat, 1) - << "incorrect value for last_msg_.use_gps_sat, expected 1, is " - << last_msg_.use_gps_sat; - EXPECT_EQ(last_msg_.use_iono_grid_point_sat_los, 7) - << "incorrect value for last_msg_.use_iono_grid_point_sat_los, expected " - "7, is " - << last_msg_.use_iono_grid_point_sat_los; - EXPECT_EQ(last_msg_.use_iono_grid_points, 5) - << "incorrect value for last_msg_.use_iono_grid_points, expected 5, is " - << last_msg_.use_iono_grid_points; - EXPECT_EQ(last_msg_.use_iono_tile_sat_los, 6) - << "incorrect value for last_msg_.use_iono_tile_sat_los, expected 6, is " - << last_msg_.use_iono_tile_sat_los; - EXPECT_EQ(last_msg_.use_tropo_grid_points, 4) - << "incorrect value for last_msg_.use_tropo_grid_points, expected 4, is " - << last_msg_.use_tropo_grid_points; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSsrFlagHighLevel, &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagHighLevel, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + for (uint8_t i = 0; i < 31; i++) { + EXPECT_EQ( + sbp_msg_ssr_flag_high_level_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_high_level_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSsrFlagHighLevel, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_high_level_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_high_level_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_high_level_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrFlagHighLevel, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.chain_id, greater.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.corr_time.tow, greater.corr_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.corr_time.wn, greater.corr_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.obs_time.tow, greater.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.obs_time.wn, greater.obs_time.wn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[0], greater.reserved[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[1], greater.reserved[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[2], greater.reserved[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[3], greater.reserved[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[4], greater.reserved[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.reserved[5], greater.reserved[5]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_sol_id, greater.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_bds_sat, greater.use_bds_sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_gal_sat, greater.use_gal_sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_gps_sat, greater.use_gps_sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_iono_grid_point_sat_los, + greater.use_iono_grid_point_sat_los); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_iono_grid_points, + greater.use_iono_grid_points); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_iono_tile_sat_los, + greater.use_iono_tile_sat_los); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_high_level_t lesser = info.test_msg; + sbp_msg_ssr_flag_high_level_t greater = info.test_msg; + make_lesser_greater(lesser.use_tropo_grid_points, + greater.use_tropo_grid_points); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagHighLevel); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_FLAG_HIGH_LEVEL"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_high_level_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ssr_flag_high_level_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_flag_high_level, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ssr_flag_high_level, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_high_level_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagHighLevel, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagHighLevel0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagHighLevel, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos.cc index 2dd620d95c..da4571d73f 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos.cc @@ -16,143 +16,725 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0() { + assign(test_msg_.faulty_los[0].constellation, 11); + assign(test_msg_.faulty_los[0].satId, 10); + + assign(test_msg_.faulty_los[1].constellation, 14); + assign(test_msg_.faulty_los[1].satId, 15); + assign(test_msg_.grid_point_id, 30); + assign(test_msg_.header.chain_id, 6); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.obs_time.tow, 180); + assign(test_msg_.header.obs_time.wn, 3); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.ssr_sol_id, 3); + assign(test_msg_.header.tile_id, 5); + assign(test_msg_.header.tile_set_id, 4); + assign(test_msg_.n_faulty_los, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_flag_iono_grid_point_sat_los_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_flag_iono_grid_point_sat_los_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagIonoGridPointSatLos, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagIonoGridPointSatLos); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_iono_grid_point_sat_los, + sizeof(msg->ssr_flag_iono_grid_point_sat_los)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_iono_grid_point_sat_los, &test_msg_, + sizeof(test_msg_)); + info.msg_type = + static_cast(SbpMsgSsrFlagIonoGridPointSatLos); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x9462; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 21; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_flag_iono_grid_point_sat_los_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_iono_grid_point_sat_los_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests( + const sbp_msg_ssr_flag_iono_grid_point_sat_los_t &lesser, + const sbp_msg_ssr_flag_iono_grid_point_sat_los_t &greater) { + sbp_msg_t wrapped_lesser = sbp::MessageTraits< + sbp_msg_ssr_flag_iono_grid_point_sat_los_t>::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = sbp::MessageTraits< + sbp_msg_ssr_flag_iono_grid_point_sat_los_t>::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_cmp(&lesser, &lesser), + 0); + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_cmp(&greater, &greater), + 0); + EXPECT_LE(sbp_msg_ssr_flag_iono_grid_point_sat_los_cmp(&lesser, &greater), + 0); + EXPECT_GT(sbp_msg_ssr_flag_iono_grid_point_sat_los_cmp(&greater, &lesser), + 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoGridPointSatLos, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoGridPointSatLos, + &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagIonoGridPointSatLos, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagIonoGridPointSatLos, + &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_iono_grid_point_sat_los_t test_msg_{}; + uint8_t encoded_frame_[21 + 8] = { 85, 209, 11, 66, 0, 21, 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 30, 0, 2, 10, 11, 15, 14, 98, 148, }; + uint8_t encoded_payload_[21] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 30, 0, 2, 10, 11, 15, 14, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp_msg_ssr_flag_iono_grid_point_sat_los_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrFlagIonoGridPointSatLos, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagIonoGridPointSatLos, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_encode( + &buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + for (uint8_t i = 0; i < 21; i++) { + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_encode( + &buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrFlagIonoGridPointSatLos, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t t{}; + return sbp_msg_ssr_flag_iono_grid_point_sat_los_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t t{}; + t.n_faulty_los = 1; + return sbp_msg_ssr_flag_iono_grid_point_sat_los_encoded_len(&t); + }() - overhead; - sbp_msg_ssr_flag_iono_grid_point_sat_los_t test_msg{}; - - test_msg.faulty_los[0].constellation = 11; - test_msg.faulty_los[0].satId = 10; - - test_msg.faulty_los[1].constellation = 14; - test_msg.faulty_los[1].satId = 15; - test_msg.grid_point_id = 30; - test_msg.header.chain_id = 6; - test_msg.header.num_msgs = 1; - test_msg.header.obs_time.tow = 180; - test_msg.header.obs_time.wn = 3; - test_msg.header.seq_num = 2; - test_msg.header.ssr_sol_id = 3; - test_msg.header.tile_id = 5; - test_msg.header.tile_set_id = 4; - test_msg.n_faulty_los = 2; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.faulty_los[0].constellation, 11) - << "incorrect value for last_msg_.faulty_los[0].constellation, expected " - "11, is " - << last_msg_.faulty_los[0].constellation; - EXPECT_EQ(last_msg_.faulty_los[0].satId, 10) - << "incorrect value for last_msg_.faulty_los[0].satId, expected 10, is " - << last_msg_.faulty_los[0].satId; - EXPECT_EQ(last_msg_.faulty_los[1].constellation, 14) - << "incorrect value for last_msg_.faulty_los[1].constellation, expected " - "14, is " - << last_msg_.faulty_los[1].constellation; - EXPECT_EQ(last_msg_.faulty_los[1].satId, 15) - << "incorrect value for last_msg_.faulty_los[1].satId, expected 15, is " - << last_msg_.faulty_los[1].satId; - EXPECT_EQ(last_msg_.grid_point_id, 30) - << "incorrect value for last_msg_.grid_point_id, expected 30, is " - << last_msg_.grid_point_id; - EXPECT_EQ(last_msg_.header.chain_id, 6) - << "incorrect value for last_msg_.header.chain_id, expected 6, is " - << last_msg_.header.chain_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.obs_time.tow, 180) - << "incorrect value for last_msg_.header.obs_time.tow, expected 180, is " - << last_msg_.header.obs_time.tow; - EXPECT_EQ(last_msg_.header.obs_time.wn, 3) - << "incorrect value for last_msg_.header.obs_time.wn, expected 3, is " - << last_msg_.header.obs_time.wn; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.ssr_sol_id, 3) - << "incorrect value for last_msg_.header.ssr_sol_id, expected 3, is " - << last_msg_.header.ssr_sol_id; - EXPECT_EQ(last_msg_.header.tile_id, 5) - << "incorrect value for last_msg_.header.tile_id, expected 5, is " - << last_msg_.header.tile_id; - EXPECT_EQ(last_msg_.header.tile_set_id, 4) - << "incorrect value for last_msg_.header.tile_set_id, expected 4, is " - << last_msg_.header.tile_set_id; - EXPECT_EQ(last_msg_.n_faulty_los, 2) - << "incorrect value for last_msg_.n_faulty_los, expected 2, is " - << last_msg_.n_faulty_los; + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_point_sat_los_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrFlagIonoGridPointSatLos, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[0].constellation, + greater.faulty_los[0].constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[0].satId, + greater.faulty_los[0].satId); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[1].constellation, + greater.faulty_los[1].constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[1].satId, + greater.faulty_los[1].satId); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.grid_point_id, greater.grid_point_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.chain_id, greater.header.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.tow, + greater.header.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.wn, greater.header.obs_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.ssr_sol_id, greater.header.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_id, greater.header.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_set_id, greater.header.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_point_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_point_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.n_faulty_los, greater.n_faulty_los); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagIonoGridPointSatLos); + EXPECT_STREQ( + sbp::MessageTraits::name, + "MSG_SSR_FLAG_IONO_GRID_POINT_SAT_LOS"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_iono_grid_point_sat_los_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_flag_iono_grid_point_sat_los_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits< + sbp_msg_ssr_flag_iono_grid_point_sat_los_t>::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ssr_flag_iono_grid_point_sat_los, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_flag_iono_grid_point_sat_los, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits:: + encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ( + sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_point_sat_los_t msg{}; + uint8_t n_read; + + EXPECT_EQ( + sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagIonoGridPointSatLos, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPointSatLos0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagIonoGridPointSatLos, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints.cc index d0077dee23..df714868a6 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints.cc @@ -16,133 +16,698 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0() { + assign(test_msg_.faulty_points[0], 10); + + assign(test_msg_.faulty_points[1], 11); + + assign(test_msg_.faulty_points[2], 12); + assign(test_msg_.header.chain_id, 6); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.obs_time.tow, 180); + assign(test_msg_.header.obs_time.wn, 3); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.ssr_sol_id, 3); + assign(test_msg_.header.tile_id, 5); + assign(test_msg_.header.tile_set_id, 4); + assign(test_msg_.n_faulty_points, 3); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_flag_iono_grid_points_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_grid_points_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_flag_iono_grid_points_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagIonoGridPoints, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_grid_points_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagIonoGridPoints); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_iono_grid_points, + sizeof(msg->ssr_flag_iono_grid_points)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_iono_grid_points_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_iono_grid_points, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrFlagIonoGridPoints); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x0735; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 21; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_flag_iono_grid_points_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_iono_grid_points_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_flag_iono_grid_points_t &lesser, + const sbp_msg_ssr_flag_iono_grid_points_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_flag_iono_grid_points_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_flag_iono_grid_points_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoGridPoints, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoGridPoints, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagIonoGridPoints, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagIonoGridPoints, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_iono_grid_points_t test_msg_{}; + uint8_t encoded_frame_[21 + 8] = { 85, 199, 11, 66, 0, 21, 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 3, 10, 0, 11, 0, 12, 0, 53, 7, }; + uint8_t encoded_payload_[21] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 3, 10, 0, 11, 0, 12, 0, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrFlagIonoGridPoints, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagIonoGridPoints, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + for (uint8_t i = 0; i < 21; i++) { + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_points_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrFlagIonoGridPoints, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_points_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_points_t msg{}; - sbp_msg_ssr_flag_iono_grid_points_t test_msg{}; - - test_msg.faulty_points[0] = 10; - - test_msg.faulty_points[1] = 11; - - test_msg.faulty_points[2] = 12; - test_msg.header.chain_id = 6; - test_msg.header.num_msgs = 1; - test_msg.header.obs_time.tow = 180; - test_msg.header.obs_time.wn = 3; - test_msg.header.seq_num = 2; - test_msg.header.ssr_sol_id = 3; - test_msg.header.tile_id = 5; - test_msg.header.tile_set_id = 4; - test_msg.n_faulty_points = 3; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.faulty_points[0], 10) - << "incorrect value for last_msg_.faulty_points[0], expected 10, is " - << last_msg_.faulty_points[0]; - EXPECT_EQ(last_msg_.faulty_points[1], 11) - << "incorrect value for last_msg_.faulty_points[1], expected 11, is " - << last_msg_.faulty_points[1]; - EXPECT_EQ(last_msg_.faulty_points[2], 12) - << "incorrect value for last_msg_.faulty_points[2], expected 12, is " - << last_msg_.faulty_points[2]; - EXPECT_EQ(last_msg_.header.chain_id, 6) - << "incorrect value for last_msg_.header.chain_id, expected 6, is " - << last_msg_.header.chain_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.obs_time.tow, 180) - << "incorrect value for last_msg_.header.obs_time.tow, expected 180, is " - << last_msg_.header.obs_time.tow; - EXPECT_EQ(last_msg_.header.obs_time.wn, 3) - << "incorrect value for last_msg_.header.obs_time.wn, expected 3, is " - << last_msg_.header.obs_time.wn; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.ssr_sol_id, 3) - << "incorrect value for last_msg_.header.ssr_sol_id, expected 3, is " - << last_msg_.header.ssr_sol_id; - EXPECT_EQ(last_msg_.header.tile_id, 5) - << "incorrect value for last_msg_.header.tile_id, expected 5, is " - << last_msg_.header.tile_id; - EXPECT_EQ(last_msg_.header.tile_set_id, 4) - << "incorrect value for last_msg_.header.tile_set_id, expected 4, is " - << last_msg_.header.tile_set_id; - EXPECT_EQ(last_msg_.n_faulty_points, 3) - << "incorrect value for last_msg_.n_faulty_points, expected 3, is " - << last_msg_.n_faulty_points; + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_flag_iono_grid_points_t t{}; + return sbp_msg_ssr_flag_iono_grid_points_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_flag_iono_grid_points_t t{}; + t.n_faulty_points = 1; + return sbp_msg_ssr_flag_iono_grid_points_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_grid_points_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrFlagIonoGridPoints, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[0], greater.faulty_points[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[1], greater.faulty_points[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[2], greater.faulty_points[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.chain_id, greater.header.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.tow, + greater.header.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.wn, greater.header.obs_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.ssr_sol_id, greater.header.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_id, greater.header.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_set_id, greater.header.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.n_faulty_points, greater.n_faulty_points); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagIonoGridPoints); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_FLAG_IONO_GRID_POINTS"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_iono_grid_points_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_flag_iono_grid_points_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_flag_iono_grid_points, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_flag_iono_grid_points, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_grid_points_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagIonoGridPoints, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoGridPoints0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagIonoGridPoints, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos.cc index 91580ed51f..b459ac1fd5 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos.cc @@ -16,139 +16,707 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0() { + assign(test_msg_.faulty_los[0].constellation, 11); + assign(test_msg_.faulty_los[0].satId, 10); + + assign(test_msg_.faulty_los[1].constellation, 14); + assign(test_msg_.faulty_los[1].satId, 15); + assign(test_msg_.header.chain_id, 6); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.obs_time.tow, 180); + assign(test_msg_.header.obs_time.wn, 3); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.ssr_sol_id, 3); + assign(test_msg_.header.tile_id, 5); + assign(test_msg_.header.tile_set_id, 4); + assign(test_msg_.n_faulty_los, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_flag_iono_tile_sat_los_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_tile_sat_los_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_flag_iono_tile_sat_los_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagIonoTileSatLos, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_iono_tile_sat_los_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagIonoTileSatLos); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_iono_tile_sat_los, + sizeof(msg->ssr_flag_iono_tile_sat_los)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_iono_tile_sat_los_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_iono_tile_sat_los, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrFlagIonoTileSatLos); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xEBEF; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 19; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_flag_iono_tile_sat_los_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_iono_tile_sat_los_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_flag_iono_tile_sat_los_t &lesser, + const sbp_msg_ssr_flag_iono_tile_sat_los_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_flag_iono_tile_sat_los_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_flag_iono_tile_sat_los_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoTileSatLos, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagIonoTileSatLos, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagIonoTileSatLos, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagIonoTileSatLos, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_iono_tile_sat_los_t test_msg_{}; + uint8_t encoded_frame_[19 + 8] = { 85, 205, 11, 66, 0, 19, 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 2, 10, 11, 15, 14, 239, 235, }; + uint8_t encoded_payload_[19] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 2, 10, 11, 15, 14, + }; +}; - sbp_msg_ssr_flag_iono_tile_sat_los_t test_msg{}; - - test_msg.faulty_los[0].constellation = 11; - test_msg.faulty_los[0].satId = 10; - - test_msg.faulty_los[1].constellation = 14; - test_msg.faulty_los[1].satId = 15; - test_msg.header.chain_id = 6; - test_msg.header.num_msgs = 1; - test_msg.header.obs_time.tow = 180; - test_msg.header.obs_time.wn = 3; - test_msg.header.seq_num = 2; - test_msg.header.ssr_sol_id = 3; - test_msg.header.tile_id = 5; - test_msg.header.tile_set_id = 4; - test_msg.n_faulty_los = 2; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.faulty_los[0].constellation, 11) - << "incorrect value for last_msg_.faulty_los[0].constellation, expected " - "11, is " - << last_msg_.faulty_los[0].constellation; - EXPECT_EQ(last_msg_.faulty_los[0].satId, 10) - << "incorrect value for last_msg_.faulty_los[0].satId, expected 10, is " - << last_msg_.faulty_los[0].satId; - EXPECT_EQ(last_msg_.faulty_los[1].constellation, 14) - << "incorrect value for last_msg_.faulty_los[1].constellation, expected " - "14, is " - << last_msg_.faulty_los[1].constellation; - EXPECT_EQ(last_msg_.faulty_los[1].satId, 15) - << "incorrect value for last_msg_.faulty_los[1].satId, expected 15, is " - << last_msg_.faulty_los[1].satId; - EXPECT_EQ(last_msg_.header.chain_id, 6) - << "incorrect value for last_msg_.header.chain_id, expected 6, is " - << last_msg_.header.chain_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.obs_time.tow, 180) - << "incorrect value for last_msg_.header.obs_time.tow, expected 180, is " - << last_msg_.header.obs_time.tow; - EXPECT_EQ(last_msg_.header.obs_time.wn, 3) - << "incorrect value for last_msg_.header.obs_time.wn, expected 3, is " - << last_msg_.header.obs_time.wn; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.ssr_sol_id, 3) - << "incorrect value for last_msg_.header.ssr_sol_id, expected 3, is " - << last_msg_.header.ssr_sol_id; - EXPECT_EQ(last_msg_.header.tile_id, 5) - << "incorrect value for last_msg_.header.tile_id, expected 5, is " - << last_msg_.header.tile_id; - EXPECT_EQ(last_msg_.header.tile_set_id, 4) - << "incorrect value for last_msg_.header.tile_set_id, expected 4, is " - << last_msg_.header.tile_set_id; - EXPECT_EQ(last_msg_.n_faulty_los, 2) - << "incorrect value for last_msg_.n_faulty_los, expected 2, is " - << last_msg_.n_faulty_los; +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrFlagIonoTileSatLos, + &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[19]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 19); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 19), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagIonoTileSatLos, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 19); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 19), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[19]; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 19), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[19]; + + for (uint8_t i = 0; i < 19; i++) { + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_tile_sat_los_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 19); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrFlagIonoTileSatLos, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 19); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_tile_sat_los_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_tile_sat_los_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_flag_iono_tile_sat_los_t t{}; + return sbp_msg_ssr_flag_iono_tile_sat_los_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_flag_iono_tile_sat_los_t t{}; + t.n_faulty_los = 1; + return sbp_msg_ssr_flag_iono_tile_sat_los_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_iono_tile_sat_los_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrFlagIonoTileSatLos, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[0].constellation, + greater.faulty_los[0].constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[0].satId, + greater.faulty_los[0].satId); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[1].constellation, + greater.faulty_los[1].constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_los[1].satId, + greater.faulty_los[1].satId); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.chain_id, greater.header.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.tow, + greater.header.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.wn, greater.header.obs_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.ssr_sol_id, greater.header.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_id, greater.header.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_set_id, greater.header.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_iono_tile_sat_los_t lesser = info.test_msg; + sbp_msg_ssr_flag_iono_tile_sat_los_t greater = info.test_msg; + make_lesser_greater(lesser.n_faulty_los, greater.n_faulty_los); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagIonoTileSatLos); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_FLAG_IONO_TILE_SAT_LOS"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_iono_tile_sat_los_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_flag_iono_tile_sat_los_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_flag_iono_tile_sat_los, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_flag_iono_tile_sat_los, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[19]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 19); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 19), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_iono_tile_sat_los_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 19); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagIonoTileSatLos, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagIonoTileSatLos0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagIonoTileSatLos, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagSatellites.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagSatellites.cc index 6f2f141fb3..b3ca40cbd9 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagSatellites.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagSatellites.cc @@ -16,129 +16,681 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagSatellites0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagSatellites0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagSatellites0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagSatellites0() { + assign(test_msg_.chain_id, 4); + assign(test_msg_.const_id, 5); + + assign(test_msg_.faulty_sats[0], 10); + + assign(test_msg_.faulty_sats[1], 11); + + assign(test_msg_.faulty_sats[2], 12); + assign(test_msg_.n_faulty_sats, 3); + assign(test_msg_.num_msgs, 1); + assign(test_msg_.obs_time.tow, 180); + assign(test_msg_.obs_time.wn, 3); + assign(test_msg_.seq_num, 2); + assign(test_msg_.ssr_sol_id, 3); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_satellites_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_flag_satellites_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagSatellites, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_satellites_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagSatellites); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_satellites, + sizeof(msg->ssr_flag_satellites)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_satellites_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_satellites, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrFlagSatellites); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xA56E; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 15; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_flag_satellites_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_satellites_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_flag_satellites_t &lesser, + const sbp_msg_ssr_flag_satellites_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_flag_satellites_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_flag_satellites_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_flag_satellites_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagSatellites, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagSatellites, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagSatellites, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagSatellites, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagSatellites0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_satellites_t test_msg_{}; + uint8_t encoded_frame_[15 + 8] = { 85, 189, 11, 66, 0, 15, 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 5, 3, 10, 11, 12, 110, 165, }; + uint8_t encoded_payload_[15] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 5, 3, 10, 11, 12, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_flag_satellites_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSsrFlagSatellites, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagSatellites, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + + for (uint8_t i = 0; i < 15; i++) { + EXPECT_EQ( + sbp_msg_ssr_flag_satellites_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_satellites_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSsrFlagSatellites, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_satellites_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_satellites_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_flag_satellites_t t{}; + return sbp_msg_ssr_flag_satellites_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_flag_satellites_t t{}; + t.n_faulty_sats = 1; + return sbp_msg_ssr_flag_satellites_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_satellites_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrFlagSatellites, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.chain_id, greater.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.const_id, greater.const_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_sats[0], greater.faulty_sats[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_sats[1], greater.faulty_sats[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_sats[2], greater.faulty_sats[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.n_faulty_sats, greater.n_faulty_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.num_msgs, greater.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.obs_time.tow, greater.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.obs_time.wn, greater.obs_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.seq_num, greater.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_satellites_t lesser = info.test_msg; + sbp_msg_ssr_flag_satellites_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_sol_id, greater.ssr_sol_id); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagSatellites); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_FLAG_SATELLITES"); +} - sbp_msg_ssr_flag_satellites_t test_msg{}; - test_msg.chain_id = 4; - test_msg.const_id = 5; - - test_msg.faulty_sats[0] = 10; - - test_msg.faulty_sats[1] = 11; - - test_msg.faulty_sats[2] = 12; - test_msg.n_faulty_sats = 3; - test_msg.num_msgs = 1; - test_msg.obs_time.tow = 180; - test_msg.obs_time.wn = 3; - test_msg.seq_num = 2; - test_msg.ssr_sol_id = 3; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.chain_id, 4) - << "incorrect value for last_msg_.chain_id, expected 4, is " - << last_msg_.chain_id; - EXPECT_EQ(last_msg_.const_id, 5) - << "incorrect value for last_msg_.const_id, expected 5, is " - << last_msg_.const_id; - EXPECT_EQ(last_msg_.faulty_sats[0], 10) - << "incorrect value for last_msg_.faulty_sats[0], expected 10, is " - << last_msg_.faulty_sats[0]; - EXPECT_EQ(last_msg_.faulty_sats[1], 11) - << "incorrect value for last_msg_.faulty_sats[1], expected 11, is " - << last_msg_.faulty_sats[1]; - EXPECT_EQ(last_msg_.faulty_sats[2], 12) - << "incorrect value for last_msg_.faulty_sats[2], expected 12, is " - << last_msg_.faulty_sats[2]; - EXPECT_EQ(last_msg_.n_faulty_sats, 3) - << "incorrect value for last_msg_.n_faulty_sats, expected 3, is " - << last_msg_.n_faulty_sats; - EXPECT_EQ(last_msg_.num_msgs, 1) - << "incorrect value for last_msg_.num_msgs, expected 1, is " - << last_msg_.num_msgs; - EXPECT_EQ(last_msg_.obs_time.tow, 180) - << "incorrect value for last_msg_.obs_time.tow, expected 180, is " - << last_msg_.obs_time.tow; - EXPECT_EQ(last_msg_.obs_time.wn, 3) - << "incorrect value for last_msg_.obs_time.wn, expected 3, is " - << last_msg_.obs_time.wn; - EXPECT_EQ(last_msg_.seq_num, 2) - << "incorrect value for last_msg_.seq_num, expected 2, is " - << last_msg_.seq_num; - EXPECT_EQ(last_msg_.ssr_sol_id, 3) - << "incorrect value for last_msg_.ssr_sol_id, expected 3, is " - << last_msg_.ssr_sol_id; +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_satellites_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ssr_flag_satellites_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_flag_satellites, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ssr_flag_satellites, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_satellites_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagSatellites, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagSatellites0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagSatellites, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints.cc b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints.cc index 061cd6e850..cf1ded7a7b 100644 --- a/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints.cc +++ b/c/test/cpp/auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints.cc @@ -16,134 +16,698 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0 + : public ::testing::Test { public: - Test_auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0() { + assign(test_msg_.faulty_points[0], 10); + + assign(test_msg_.faulty_points[1], 11); + + assign(test_msg_.faulty_points[2], 12); + assign(test_msg_.header.chain_id, 6); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.obs_time.tow, 180); + assign(test_msg_.header.obs_time.wn, 3); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.ssr_sol_id, 3); + assign(test_msg_.header.tile_id, 5); + assign(test_msg_.header.tile_set_id, 4); + assign(test_msg_.n_faulty_points, 3); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_flag_tropo_grid_points_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_tropo_grid_points_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_flag_tropo_grid_points_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrFlagTropoGridPoints, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_flag_tropo_grid_points_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrFlagTropoGridPoints); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_flag_tropo_grid_points, + sizeof(msg->ssr_flag_tropo_grid_points)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_flag_tropo_grid_points_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_flag_tropo_grid_points, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrFlagTropoGridPoints); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x96F3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 21; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_flag_tropo_grid_points_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_flag_tropo_grid_points_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_flag_tropo_grid_points_t &lesser, + const sbp_msg_ssr_flag_tropo_grid_points_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_flag_tropo_grid_points_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_flag_tropo_grid_points_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagTropoGridPoints, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrFlagTropoGridPoints, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrFlagTropoGridPoints, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrFlagTropoGridPoints, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_flag_tropo_grid_points_t test_msg_{}; + uint8_t encoded_frame_[21 + 8] = { 85, 195, 11, 66, 0, 21, 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 3, 10, 0, 11, 0, 12, 0, 243, 150, }; + uint8_t encoded_payload_[21] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 4, 0, 5, 0, 6, 3, 10, 0, 11, 0, 12, 0, + }; +}; + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrFlagTropoGridPoints, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrFlagTropoGridPoints, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + + for (uint8_t i = 0; i < 21; i++) { + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_tropo_grid_points_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrFlagTropoGridPoints, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_tropo_grid_points_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_tropo_grid_points_t msg{}; - sbp_msg_ssr_flag_tropo_grid_points_t test_msg{}; - - test_msg.faulty_points[0] = 10; - - test_msg.faulty_points[1] = 11; - - test_msg.faulty_points[2] = 12; - test_msg.header.chain_id = 6; - test_msg.header.num_msgs = 1; - test_msg.header.obs_time.tow = 180; - test_msg.header.obs_time.wn = 3; - test_msg.header.seq_num = 2; - test_msg.header.ssr_sol_id = 3; - test_msg.header.tile_id = 5; - test_msg.header.tile_set_id = 4; - test_msg.n_faulty_points = 3; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.faulty_points[0], 10) - << "incorrect value for last_msg_.faulty_points[0], expected 10, is " - << last_msg_.faulty_points[0]; - EXPECT_EQ(last_msg_.faulty_points[1], 11) - << "incorrect value for last_msg_.faulty_points[1], expected 11, is " - << last_msg_.faulty_points[1]; - EXPECT_EQ(last_msg_.faulty_points[2], 12) - << "incorrect value for last_msg_.faulty_points[2], expected 12, is " - << last_msg_.faulty_points[2]; - EXPECT_EQ(last_msg_.header.chain_id, 6) - << "incorrect value for last_msg_.header.chain_id, expected 6, is " - << last_msg_.header.chain_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.obs_time.tow, 180) - << "incorrect value for last_msg_.header.obs_time.tow, expected 180, is " - << last_msg_.header.obs_time.tow; - EXPECT_EQ(last_msg_.header.obs_time.wn, 3) - << "incorrect value for last_msg_.header.obs_time.wn, expected 3, is " - << last_msg_.header.obs_time.wn; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.ssr_sol_id, 3) - << "incorrect value for last_msg_.header.ssr_sol_id, expected 3, is " - << last_msg_.header.ssr_sol_id; - EXPECT_EQ(last_msg_.header.tile_id, 5) - << "incorrect value for last_msg_.header.tile_id, expected 5, is " - << last_msg_.header.tile_id; - EXPECT_EQ(last_msg_.header.tile_set_id, 4) - << "incorrect value for last_msg_.header.tile_set_id, expected 4, is " - << last_msg_.header.tile_set_id; - EXPECT_EQ(last_msg_.n_faulty_points, 3) - << "incorrect value for last_msg_.n_faulty_points, expected 3, is " - << last_msg_.n_faulty_points; + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_flag_tropo_grid_points_t t{}; + return sbp_msg_ssr_flag_tropo_grid_points_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_flag_tropo_grid_points_t t{}; + t.n_faulty_points = 1; + return sbp_msg_ssr_flag_tropo_grid_points_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_flag_tropo_grid_points_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrFlagTropoGridPoints, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[0], greater.faulty_points[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[1], greater.faulty_points[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.faulty_points[2], greater.faulty_points[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.chain_id, greater.header.chain_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.tow, + greater.header.obs_time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.obs_time.wn, greater.header.obs_time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.ssr_sol_id, greater.header.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_id, greater.header.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.header.tile_set_id, greater.header.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_flag_tropo_grid_points_t lesser = info.test_msg; + sbp_msg_ssr_flag_tropo_grid_points_t greater = info.test_msg; + make_lesser_greater(lesser.n_faulty_points, greater.n_faulty_points); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrFlagTropoGridPoints); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_FLAG_TROPO_GRID_POINTS"); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_flag_tropo_grid_points_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_flag_tropo_grid_points_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_flag_tropo_grid_points, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_flag_tropo_grid_points, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[21]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 21); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 21), 0); } + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_flag_tropo_grid_points_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 21); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrFlagTropoGridPoints, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_integrity_MsgSsrFlagTropoGridPoints0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrFlagTropoGridPoints, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_logging_MsgFwd.cc b/c/test/cpp/auto_check_sbp_logging_MsgFwd.cc index 2462b3c112..ca5a3198d2 100644 --- a/c/test/cpp/auto_check_sbp_logging_MsgFwd.cc +++ b/c/test/cpp/auto_check_sbp_logging_MsgFwd.cc @@ -16,172 +16,721 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_logging_MsgFwd0 : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_logging_MsgFwd0 : public ::testing::Test { public: - Test_auto_check_sbp_logging_MsgFwd0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_logging_MsgFwd0() { + assign(test_msg_.fwd_payload[0], 86); + + assign(test_msg_.fwd_payload[1], 81); + + assign(test_msg_.fwd_payload[2], 68); + + assign(test_msg_.fwd_payload[3], 47); + + assign(test_msg_.fwd_payload[4], 81); + + assign(test_msg_.fwd_payload[5], 103); + + assign(test_msg_.fwd_payload[6], 65); + + assign(test_msg_.fwd_payload[7], 69); + + assign(test_msg_.fwd_payload[8], 65); + + assign(test_msg_.fwd_payload[9], 65); + + assign(test_msg_.fwd_payload[10], 65); + + assign(test_msg_.fwd_payload[11], 65); + + assign(test_msg_.fwd_payload[12], 65); + + assign(test_msg_.fwd_payload[13], 69); + + assign(test_msg_.fwd_payload[14], 97); + + assign(test_msg_.fwd_payload[15], 103); + assign(test_msg_.n_fwd_payload, 16); + assign(test_msg_.protocol, 0); + assign(test_msg_.source, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_fwd_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, const sbp_msg_fwd_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgFwd, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_fwd_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgFwd); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->fwd, sizeof(msg->fwd)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_fwd_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.fwd, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgFwd); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x5f7d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 18; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_fwd_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_fwd_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_fwd_t &lesser, + const sbp_msg_fwd_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_fwd_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_fwd_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_fwd_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_fwd_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgFwd, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgFwd, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgFwd, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT(sbp_message_cmp(SbpMsgFwd, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_logging_MsgFwd0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_fwd_t test_msg_{}; + uint8_t encoded_frame_[18 + 8] = { 85, 2, 4, 66, 0, 18, 0, 0, 86, 81, 68, 47, 81, 103, 65, 69, 65, 65, 65, 65, 65, 69, 97, 103, 125, 95, }; + uint8_t encoded_payload_[18] = { + 0, 0, 86, 81, 68, 47, 81, 103, 65, 69, 65, 65, 65, 65, 65, 69, 97, 103, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_fwd_encoded_len(&info.test_msg), info.payload_len); - sbp_msg_fwd_t test_msg{}; - - test_msg.fwd_payload[0] = 86; - - test_msg.fwd_payload[1] = 81; - - test_msg.fwd_payload[2] = 68; - - test_msg.fwd_payload[3] = 47; - - test_msg.fwd_payload[4] = 81; - - test_msg.fwd_payload[5] = 103; - - test_msg.fwd_payload[6] = 65; - - test_msg.fwd_payload[7] = 69; - - test_msg.fwd_payload[8] = 65; - - test_msg.fwd_payload[9] = 65; - - test_msg.fwd_payload[10] = 65; - - test_msg.fwd_payload[11] = 65; - - test_msg.fwd_payload[12] = 65; - - test_msg.fwd_payload[13] = 69; - - test_msg.fwd_payload[14] = 97; - - test_msg.fwd_payload[15] = 103; - test_msg.n_fwd_payload = 16; - test_msg.protocol = 0; - test_msg.source = 0; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.fwd_payload[0], 86) - << "incorrect value for last_msg_.fwd_payload[0], expected 86, is " - << last_msg_.fwd_payload[0]; - EXPECT_EQ(last_msg_.fwd_payload[1], 81) - << "incorrect value for last_msg_.fwd_payload[1], expected 81, is " - << last_msg_.fwd_payload[1]; - EXPECT_EQ(last_msg_.fwd_payload[2], 68) - << "incorrect value for last_msg_.fwd_payload[2], expected 68, is " - << last_msg_.fwd_payload[2]; - EXPECT_EQ(last_msg_.fwd_payload[3], 47) - << "incorrect value for last_msg_.fwd_payload[3], expected 47, is " - << last_msg_.fwd_payload[3]; - EXPECT_EQ(last_msg_.fwd_payload[4], 81) - << "incorrect value for last_msg_.fwd_payload[4], expected 81, is " - << last_msg_.fwd_payload[4]; - EXPECT_EQ(last_msg_.fwd_payload[5], 103) - << "incorrect value for last_msg_.fwd_payload[5], expected 103, is " - << last_msg_.fwd_payload[5]; - EXPECT_EQ(last_msg_.fwd_payload[6], 65) - << "incorrect value for last_msg_.fwd_payload[6], expected 65, is " - << last_msg_.fwd_payload[6]; - EXPECT_EQ(last_msg_.fwd_payload[7], 69) - << "incorrect value for last_msg_.fwd_payload[7], expected 69, is " - << last_msg_.fwd_payload[7]; - EXPECT_EQ(last_msg_.fwd_payload[8], 65) - << "incorrect value for last_msg_.fwd_payload[8], expected 65, is " - << last_msg_.fwd_payload[8]; - EXPECT_EQ(last_msg_.fwd_payload[9], 65) - << "incorrect value for last_msg_.fwd_payload[9], expected 65, is " - << last_msg_.fwd_payload[9]; - EXPECT_EQ(last_msg_.fwd_payload[10], 65) - << "incorrect value for last_msg_.fwd_payload[10], expected 65, is " - << last_msg_.fwd_payload[10]; - EXPECT_EQ(last_msg_.fwd_payload[11], 65) - << "incorrect value for last_msg_.fwd_payload[11], expected 65, is " - << last_msg_.fwd_payload[11]; - EXPECT_EQ(last_msg_.fwd_payload[12], 65) - << "incorrect value for last_msg_.fwd_payload[12], expected 65, is " - << last_msg_.fwd_payload[12]; - EXPECT_EQ(last_msg_.fwd_payload[13], 69) - << "incorrect value for last_msg_.fwd_payload[13], expected 69, is " - << last_msg_.fwd_payload[13]; - EXPECT_EQ(last_msg_.fwd_payload[14], 97) - << "incorrect value for last_msg_.fwd_payload[14], expected 97, is " - << last_msg_.fwd_payload[14]; - EXPECT_EQ(last_msg_.fwd_payload[15], 103) - << "incorrect value for last_msg_.fwd_payload[15], expected 103, is " - << last_msg_.fwd_payload[15]; - EXPECT_EQ(last_msg_.n_fwd_payload, 16) - << "incorrect value for last_msg_.n_fwd_payload, expected 16, is " - << last_msg_.n_fwd_payload; - EXPECT_EQ(last_msg_.protocol, 0) - << "incorrect value for last_msg_.protocol, expected 0, is " - << last_msg_.protocol; - EXPECT_EQ(last_msg_.source, 0) - << "incorrect value for last_msg_.source, expected 0, is " - << last_msg_.source; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgFwd, &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[18]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_fwd_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 18); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 18), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgFwd, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 18); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 18), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[18]; + + EXPECT_EQ(sbp_msg_fwd_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 18), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgFwd0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[18]; + + for (uint8_t i = 0; i < 18; i++) { + EXPECT_EQ(sbp_msg_fwd_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_fwd_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_fwd_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 18); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgFwd, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 18); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_fwd_t msg{}; + + EXPECT_EQ(sbp_msg_fwd_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgFwd0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_fwd_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_fwd_t t{}; + return sbp_msg_fwd_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_fwd_t t{}; + t.n_fwd_payload = 1; + return sbp_msg_fwd_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_fwd_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_fwd_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgFwd, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[0], greater.fwd_payload[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[1], greater.fwd_payload[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[2], greater.fwd_payload[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[3], greater.fwd_payload[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[4], greater.fwd_payload[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[5], greater.fwd_payload[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[6], greater.fwd_payload[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[7], greater.fwd_payload[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[8], greater.fwd_payload[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[9], greater.fwd_payload[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[10], greater.fwd_payload[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[11], greater.fwd_payload[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[12], greater.fwd_payload[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[13], greater.fwd_payload[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[14], greater.fwd_payload[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.fwd_payload[15], greater.fwd_payload[15]); + comparison_tests(lesser, greater); + } + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.n_fwd_payload, greater.n_fwd_payload); + comparison_tests(lesser, greater); + } + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.protocol, greater.protocol); + comparison_tests(lesser, greater); + } + { + sbp_msg_fwd_t lesser = info.test_msg; + sbp_msg_fwd_t greater = info.test_msg; + make_lesser_greater(lesser.source, greater.source); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgFwd); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_FWD"); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_fwd_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_fwd_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.fwd, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.fwd, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[18]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 18); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 18), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_fwd_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 18); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgFwd, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgFwd0, SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgFwd, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_logging_MsgLog.cc b/c/test/cpp/auto_check_sbp_logging_MsgLog.cc index d9cfb1cc46..07a7798af3 100644 --- a/c/test/cpp/auto_check_sbp_logging_MsgLog.cc +++ b/c/test/cpp/auto_check_sbp_logging_MsgLog.cc @@ -16,97 +16,702 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_logging_MsgLog0 : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_logging_MsgLog0 : public ::testing::Test { public: - Test_auto_check_sbp_logging_MsgLog0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } + Testauto_check_sbp_logging_MsgLog0() { + assign(test_msg_.level, 6); - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; + size_t written; + EXPECT_TRUE(sbp_msg_log_text_set( + &test_msg_, "Filtered all obs from 2314 at tow 83.539019", false, + &written)); + EXPECT_EQ(written, strlen("Filtered all obs from 2314 at tow 83.539019")); + EXPECT_EQ(sbp_msg_log_text_encoded_len(&test_msg_), 43); } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_log_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, const sbp_msg_log_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgLog, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_log_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgLog); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->log, sizeof(msg->log)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_log_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.log, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgLog); + info.sender_id = 2314; + info.preamble = 0x55; + info.crc = 0xa3b1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 44; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_log_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_log_t &lesser, + const sbp_msg_log_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_log_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_log_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_log_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_log_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgLog, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgLog, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgLog, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT(sbp_message_cmp(SbpMsgLog, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_log_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_logging_MsgLog0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_log_t test_msg_{}; + uint8_t encoded_frame_[44 + 8] = { 85, 1, 4, 10, 9, 44, 6, 70, 105, 108, 116, 101, 114, 101, 100, 32, 97, 108, 108, 32, 111, 98, 115, 32, 102, 114, 111, 109, 32, 50, 51, 49, 52, 32, 97, 116, 32, 116, 111, 119, 32, 56, 51, 46, 53, 51, 57, 48, 49, 57, 177, 163, }; + uint8_t encoded_payload_[44] = { + 6, 70, 105, 108, 116, 101, 114, 101, 100, 32, 97, 108, 108, 32, 111, + 98, 115, 32, 102, 114, 111, 109, 32, 50, 51, 49, 52, 32, 97, 116, + 32, 116, 111, 119, 32, 56, 51, 46, 53, 51, 57, 48, 49, 57, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgLog0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_log_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgLog, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[44]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_log_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 44); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 44), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgLog, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 44); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 44), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[44]; + + EXPECT_EQ(sbp_msg_log_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 44), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgLog0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[44]; + + for (uint8_t i = 0; i < 44; i++) { + EXPECT_EQ(sbp_msg_log_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_log_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_log_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 44); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgLog, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 44); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_log_t msg{}; + + EXPECT_EQ(sbp_msg_log_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgLog0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_log_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_LOG_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_log_t t{}; return + // sbp_msg_log_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_log_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - sbp_msg_log_t test_msg{}; - test_msg.level = 6; + EXPECT_EQ(sbp_msg_log_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgLog, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_log_t lesser = info.test_msg; + sbp_msg_log_t greater = info.test_msg; + make_lesser_greater(lesser.level, greater.level); + comparison_tests(lesser, greater); + } + { + sbp_msg_log_t lesser = info.test_msg; + sbp_msg_log_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgLog); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_LOG"); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_log_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_log_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.log, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.log, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[44]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 44); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 44), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_log_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 44); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgLog, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0, SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgLog, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgLog0_text + : public Testauto_check_sbp_logging_MsgLog0 {}; + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, StringInit) { + sbp_msg_log_t t{}; + sbp_msg_log_text_init(&t); + EXPECT_TRUE(sbp_msg_log_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, IsValid) { + sbp_msg_log_t t{}; size_t written; EXPECT_TRUE(sbp_msg_log_text_set( - &test_msg, "Filtered all obs from 2314 at tow 83.539019", false, - &written)); + &t, "Filtered all obs from 2314 at tow 83.539019", false, &written)); EXPECT_EQ(written, strlen("Filtered all obs from 2314 at tow 83.539019")); - EXPECT_EQ(sbp_msg_log_text_encoded_len(&test_msg), 43); + EXPECT_EQ(sbp_msg_log_text_encoded_len(&t), 43); + EXPECT_TRUE(sbp_msg_log_text_valid(&t)); +} - EXPECT_EQ(send_message(2314, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, SpaceRemaining) { + sbp_msg_log_t t{}; + size_t empty_space_remaining = sbp_msg_log_text_space_remaining(&t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + size_t written; + EXPECT_TRUE(sbp_msg_log_text_set( + &t, "Filtered all obs from 2314 at tow 83.539019", false, &written)); + EXPECT_EQ(written, strlen("Filtered all obs from 2314 at tow 83.539019")); + EXPECT_EQ(sbp_msg_log_text_encoded_len(&t), 43); + size_t assigned_space_remaining = sbp_msg_log_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_log_t t{}; + + size_t nwritten{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 2314); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.level, 6) - << "incorrect value for last_msg_.level, expected 6, is " - << last_msg_.level; + EXPECT_TRUE(sbp_msg_log_text_set_raw(&t, info.test_msg.text.data, + sbp_msg_log_text_strlen(&info.test_msg), + false, &nwritten)); + EXPECT_EQ(sbp_msg_log_text_encoded_len(&info.test_msg), + sbp_msg_log_text_encoded_len(&t)); +} - EXPECT_EQ(sbp_msg_log_text_encoded_len(&last_msg_), 43); - EXPECT_STREQ(sbp_msg_log_text_get(&last_msg_), +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, Set) { + sbp_msg_log_t t{}; + size_t nwritten{}; + const char *text = "Filtered all obs from 2314 at tow 83.539019"; + + EXPECT_TRUE(sbp_msg_log_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_log_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, Printf) { + sbp_msg_log_t t{}; + size_t nwritten{}; + const char *text = "Filtered all obs from 2314 at tow 83.539019"; + + EXPECT_TRUE(sbp_msg_log_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_log_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, Vprintf) { + sbp_msg_log_t t{}; + size_t nwritten{}; + const char *text = "Filtered all obs from 2314 at tow 83.539019"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_log_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_log_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, AppendPrintf) { + sbp_msg_log_t t{}; + size_t nwritten{}; + char part1[] = "Filtered all obs from 2314 at tow 83.539019"; + char part2[] = "Filtered all obs from 2314 at tow 83.539019"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_log_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_log_text_get(&t), &part1[0]); + + EXPECT_TRUE( + sbp_msg_log_text_append_printf(&t, false, &nwritten, "%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_log_text_get(&t), + "Filtered all obs from 2314 at tow 83.539019"); +} + +TEST_F(Testauto_check_sbp_logging_MsgLog0_text, AppendVprintf) { + sbp_msg_log_t t{}; + size_t nwritten{}; + char part1[] = "Filtered all obs from 2314 at tow 83.539019"; + char part2[] = "Filtered all obs from 2314 at tow 83.539019"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_log_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_log_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_log_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_log_text_get(&t), "Filtered all obs from 2314 at tow 83.539019"); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_logging_MsgPrintDep.cc b/c/test/cpp/auto_check_sbp_logging_MsgPrintDep.cc index 2aa8b950da..676cbaacce 100644 --- a/c/test/cpp/auto_check_sbp_logging_MsgPrintDep.cc +++ b/c/test/cpp/auto_check_sbp_logging_MsgPrintDep.cc @@ -16,535 +16,4149 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_logging_MsgPrintDep0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_logging_MsgPrintDep0 : public ::testing::Test { public: - Test_auto_check_sbp_logging_MsgPrintDep0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_logging_MsgPrintDep0() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n", false, + &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 43); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0x6774; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 43; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[43 + 8] = { 85, 16, 0, 34, 34, 43, 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, 80, 82, 78, 32, 49, 53, 32, 102, 111, 117, 110, 100, 32, 64, 32, 45, 50, 52, 57, 55, 32, 72, 122, 44, 32, 50, 48, 32, 83, 78, 82, 10, 116, 103, }; + uint8_t encoded_payload_[43] = { + 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, 80, 82, 78, 32, + 49, 53, 32, 102, 111, 117, 110, 100, 32, 64, 32, 45, 50, 52, 57, + 55, 32, 72, 122, 44, 32, 50, 48, 32, 83, 78, 82, 10, + }; +}; - sbp_msg_print_dep_t test_msg{}; +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); - size_t written; - EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n", false, - &written)); - EXPECT_EQ(written, strlen("INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 43); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[43]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 43); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 43), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 43); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 43), 0); +} - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[43]; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 43), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[43]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 43; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 43); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"); + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 43); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 43); + EXPECT_EQ(msg, info.test_msg); } -class Test_auto_check_sbp_logging_MsgPrintDep1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_logging_MsgPrintDep1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep1, Test) { - uint8_t encoded_frame[] = { - 85, 16, 0, 34, 34, 42, 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, - 80, 82, 78, 32, 51, 49, 32, 102, 111, 117, 110, 100, 32, 64, 32, 52, 50, - 52, 53, 32, 72, 122, 44, 32, 50, 49, 32, 83, 78, 82, 10, 140, 43, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_print_dep_t test_msg{}; + CHandler handler{&state}; - size_t written; - EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n", false, - &written)); - EXPECT_EQ(written, strlen("INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 42); + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 42); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } -class Test_auto_check_sbp_logging_MsgPrintDep2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_logging_MsgPrintDep2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[43]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 43); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 43), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 43); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep2, Test) { - uint8_t encoded_frame[] = { - 85, 16, 0, 34, 34, 35, 73, 78, 70, 79, 58, 32, 68, 105, 115, - 97, 98, 108, 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, - 48, 32, 40, 80, 82, 78, 32, 49, 49, 41, 10, 23, 143, - }; +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); - sbp_msg_print_dep_t test_msg{}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep0_text + : public Testauto_check_sbp_logging_MsgPrintDep0 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, IsValid) { + sbp_msg_print_dep_t t{}; size_t written; EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: Disabling channel 0 (PRN 11)\n", false, &written)); - EXPECT_EQ(written, strlen("INFO: Disabling channel 0 (PRN 11)\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 35); + &t, "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 43); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 43); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); + size_t nwritten{}; - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 35); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: Disabling channel 0 (PRN 11)\n"); + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); } -class Test_auto_check_sbp_logging_MsgPrintDep3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_logging_MsgPrintDep3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep3, Test) { - uint8_t encoded_frame[] = { - 85, 16, 0, 34, 34, 41, 73, 78, 70, 79, 58, 32, 97, - 99, 113, 58, 32, 80, 82, 78, 32, 50, 32, 102, 111, 117, - 110, 100, 32, 64, 32, 51, 57, 57, 54, 32, 72, 122, 44, - 32, 50, 48, 32, 83, 78, 82, 10, 239, 48, + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; }; - sbp_msg_print_dep_t test_msg{}; + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} - size_t written; - EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n", false, - &written)); - EXPECT_EQ(written, strlen("INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 41); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); + part1[1] = 0; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); - while (dummy_rd_ < dummy_wr_) { - process(); - } + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"); +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep0_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"; - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 41); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"); + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 15 found @ -2497 Hz, 20 SNR\n"); } -class Test_auto_check_sbp_logging_MsgPrintDep4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + +class Testauto_check_sbp_logging_MsgPrintDep1 : public ::testing::Test { public: - Test_auto_check_sbp_logging_MsgPrintDep4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_logging_MsgPrintDep1() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n", false, + &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 42); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep4, Test) { - uint8_t encoded_frame[] = { - 85, 16, 0, 34, 34, 42, 73, 78, 70, 79, 58, 32, 97, - 99, 113, 58, 32, 80, 82, 78, 32, 52, 32, 102, 111, 117, - 110, 100, 32, 64, 32, 45, 55, 52, 57, 50, 32, 72, 122, - 44, 32, 50, 48, 32, 83, 78, 82, 10, 47, 248, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_print_dep_t test_msg{}; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - size_t written; - EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n", false, - &written)); - EXPECT_EQ(written, strlen("INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 42); + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); + uint32_t remaining() const noexcept { return max_len_ - offset_; } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + const uint8_t *data() const noexcept { return buf_; } - while (dummy_rd_ < dummy_wr_) { - process(); - } + uint32_t len() const noexcept { return offset_; } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 42); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"); -} -class Test_auto_check_sbp_logging_MsgPrintDep5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_logging_MsgPrintDep5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0x2b8c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_print_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_print_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_logging_MsgPrintDep5, Test) { - uint8_t encoded_frame[] = { - 85, 16, 0, 34, 34, 35, 73, 78, 70, 79, 58, 32, 68, 105, 115, - 97, 98, 108, 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, - 49, 32, 40, 80, 82, 78, 32, 49, 53, 41, 10, 158, 139, + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { + 85, 16, 0, 34, 34, 42, 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, + 80, 82, 78, 32, 51, 49, 32, 102, 111, 117, 110, 100, 32, 64, 32, 52, 50, + 52, 53, 32, 72, 122, 44, 32, 50, 49, 32, 83, 78, 82, 10, 140, 43, + }; + uint8_t encoded_payload_[42] = { + 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, 80, 82, 78, + 32, 51, 49, 32, 102, 111, 117, 110, 100, 32, 64, 32, 52, 50, + 52, 53, 32, 72, 122, 44, 32, 50, 49, 32, 83, 78, 82, 10, }; +}; - sbp_msg_print_dep_t test_msg{}; +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); - size_t written; - EXPECT_TRUE(sbp_msg_print_dep_text_set( - &test_msg, "INFO: Disabling channel 1 (PRN 15)\n", false, &written)); - EXPECT_EQ(written, strlen("INFO: Disabling channel 1 (PRN 15)\n")); - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg), 35); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; - EXPECT_EQ(send_message(8738, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 8738); - EXPECT_EQ(last_msg_, test_msg); +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; - EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&last_msg_), 35); - EXPECT_STREQ(sbp_msg_print_dep_text_get(&last_msg_), - "INFO: Disabling channel 1 (PRN 15)\n"); + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep1_text + : public Testauto_check_sbp_logging_MsgPrintDep1 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, IsValid) { + sbp_msg_print_dep_t t{}; + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 42); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 42); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; + + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + char part2[] = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep1_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + char part2[] = "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 31 found @ 4245 Hz, 21 SNR\n"); +} + +class Testauto_check_sbp_logging_MsgPrintDep2 : public ::testing::Test { + public: + Testauto_check_sbp_logging_MsgPrintDep2() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: Disabling channel 0 (PRN 11)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 0 (PRN 11)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 35); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0x8f17; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 35; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[35 + 8] = { + 85, 16, 0, 34, 34, 35, 73, 78, 70, 79, 58, 32, 68, 105, 115, + 97, 98, 108, 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, + 48, 32, 40, 80, 82, 78, 32, 49, 49, 41, 10, 23, 143, + }; + uint8_t encoded_payload_[35] = { + 73, 78, 70, 79, 58, 32, 68, 105, 115, 97, 98, 108, + 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, + 48, 32, 40, 80, 82, 78, 32, 49, 49, 41, 10, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + for (uint8_t i = 0; i < 35; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep2_text + : public Testauto_check_sbp_logging_MsgPrintDep2 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, IsValid) { + sbp_msg_print_dep_t t{}; + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: Disabling channel 0 (PRN 11)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 0 (PRN 11)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 35); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: Disabling channel 0 (PRN 11)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 0 (PRN 11)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 35); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; + + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 0 (PRN 11)\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 0 (PRN 11)\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 0 (PRN 11)\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: Disabling channel 0 (PRN 11)\n"; + char part2[] = "INFO: Disabling channel 0 (PRN 11)\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: Disabling channel 0 (PRN 11)\n"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep2_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: Disabling channel 0 (PRN 11)\n"; + char part2[] = "INFO: Disabling channel 0 (PRN 11)\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: Disabling channel 0 (PRN 11)\n"); +} + +class Testauto_check_sbp_logging_MsgPrintDep3 : public ::testing::Test { + public: + Testauto_check_sbp_logging_MsgPrintDep3() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n", false, + &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 41); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0x30ef; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 41; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[41 + 8] = { + 85, 16, 0, 34, 34, 41, 73, 78, 70, 79, 58, 32, 97, + 99, 113, 58, 32, 80, 82, 78, 32, 50, 32, 102, 111, 117, + 110, 100, 32, 64, 32, 51, 57, 57, 54, 32, 72, 122, 44, + 32, 50, 48, 32, 83, 78, 82, 10, 239, 48, + }; + uint8_t encoded_payload_[41] = { + 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, 80, 82, 78, + 32, 50, 32, 102, 111, 117, 110, 100, 32, 64, 32, 51, 57, 57, + 54, 32, 72, 122, 44, 32, 50, 48, 32, 83, 78, 82, 10, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + + for (uint8_t i = 0; i < 41; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep3_text + : public Testauto_check_sbp_logging_MsgPrintDep3 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, IsValid) { + sbp_msg_print_dep_t t{}; + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 41); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 41); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; + + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep3_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 2 found @ 3996 Hz, 20 SNR\n"); +} + +class Testauto_check_sbp_logging_MsgPrintDep4 : public ::testing::Test { + public: + Testauto_check_sbp_logging_MsgPrintDep4() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n", false, + &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 42); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0xf82f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { + 85, 16, 0, 34, 34, 42, 73, 78, 70, 79, 58, 32, 97, + 99, 113, 58, 32, 80, 82, 78, 32, 52, 32, 102, 111, 117, + 110, 100, 32, 64, 32, 45, 55, 52, 57, 50, 32, 72, 122, + 44, 32, 50, 48, 32, 83, 78, 82, 10, 47, 248, + }; + uint8_t encoded_payload_[42] = { + 73, 78, 70, 79, 58, 32, 97, 99, 113, 58, 32, 80, 82, 78, + 32, 52, 32, 102, 111, 117, 110, 100, 32, 64, 32, 45, 55, 52, + 57, 50, 32, 72, 122, 44, 32, 50, 48, 32, 83, 78, 82, 10, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep4_text + : public Testauto_check_sbp_logging_MsgPrintDep4 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, IsValid) { + sbp_msg_print_dep_t t{}; + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 42); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 42); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; + + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep4_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + char part2[] = "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: acq: PRN 4 found @ -7492 Hz, 20 SNR\n"); +} + +class Testauto_check_sbp_logging_MsgPrintDep5 : public ::testing::Test { + public: + Testauto_check_sbp_logging_MsgPrintDep5() { + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &test_msg_, "INFO: Disabling channel 1 (PRN 15)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 1 (PRN 15)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&test_msg_), 35); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_print_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPrintDep, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_print_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPrintDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->print_dep, sizeof(msg->print_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_print_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.print_dep, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPrintDep); + info.sender_id = 8738; + info.preamble = 0x55; + info.crc = 0x8b9e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 35; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_print_dep_t &lesser, + const sbp_msg_print_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_print_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_print_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_print_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_print_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPrintDep, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_print_dep_t test_msg_{}; + uint8_t encoded_frame_[35 + 8] = { + 85, 16, 0, 34, 34, 35, 73, 78, 70, 79, 58, 32, 68, 105, 115, + 97, 98, 108, 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, + 49, 32, 40, 80, 82, 78, 32, 49, 53, 41, 10, 158, 139, + }; + uint8_t encoded_payload_[35] = { + 73, 78, 70, 79, 58, 32, 68, 105, 115, 97, 98, 108, + 105, 110, 103, 32, 99, 104, 97, 110, 110, 101, 108, 32, + 49, 32, 40, 80, 82, 78, 32, 49, 53, 41, 10, + }; +}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_print_dep_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPrintDep, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPrintDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + EXPECT_EQ( + sbp_msg_print_dep_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + for (uint8_t i = 0; i < 35; i++) { + EXPECT_EQ(sbp_msg_print_dep_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPrintDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + EXPECT_EQ(sbp_msg_print_dep_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_PRINT_DEP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_print_dep_t t{}; return + // sbp_msg_print_dep_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_print_dep_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_print_dep_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPrintDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_print_dep_t lesser = info.test_msg; + sbp_msg_print_dep_t greater = info.test_msg; + make_lesser_greater(lesser.text, greater.text); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPrintDep); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_PRINT_DEP"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_print_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_print_dep_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.print_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.print_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPrintDep, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPrintDep, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_logging_MsgPrintDep5_text + : public Testauto_check_sbp_logging_MsgPrintDep5 {}; + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, StringInit) { + sbp_msg_print_dep_t t{}; + sbp_msg_print_dep_text_init(&t); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, IsValid) { + sbp_msg_print_dep_t t{}; + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: Disabling channel 1 (PRN 15)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 1 (PRN 15)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 35); + EXPECT_TRUE(sbp_msg_print_dep_text_valid(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, SpaceRemaining) { + sbp_msg_print_dep_t t{}; + size_t empty_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + + size_t written; + EXPECT_TRUE(sbp_msg_print_dep_text_set( + &t, "INFO: Disabling channel 1 (PRN 15)\n", false, &written)); + EXPECT_EQ(written, strlen("INFO: Disabling channel 1 (PRN 15)\n")); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&t), 35); + size_t assigned_space_remaining = sbp_msg_print_dep_text_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_print_dep_t t{}; + + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_print_dep_text_set_raw( + &t, info.test_msg.text.data, + sbp_msg_print_dep_text_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_print_dep_text_encoded_len(&info.test_msg), + sbp_msg_print_dep_text_encoded_len(&t)); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, Set) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 1 (PRN 15)\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, Printf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 1 (PRN 15)\n"; + + EXPECT_TRUE(sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, Vprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + const char *text = "INFO: Disabling channel 1 (PRN 15)\n"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_print_dep_text_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), text); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, AppendPrintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: Disabling channel 1 (PRN 15)\n"; + char part2[] = "INFO: Disabling channel 1 (PRN 15)\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_print_dep_text_append_printf(&t, false, &nwritten, "%s", + &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: Disabling channel 1 (PRN 15)\n"); +} + +TEST_F(Testauto_check_sbp_logging_MsgPrintDep5_text, AppendVprintf) { + sbp_msg_print_dep_t t{}; + size_t nwritten{}; + char part1[] = "INFO: Disabling channel 1 (PRN 15)\n"; + char part2[] = "INFO: Disabling channel 1 (PRN 15)\n"; + + part1[1] = 0; + + EXPECT_TRUE( + sbp_msg_print_dep_text_printf(&t, false, &nwritten, "%s", &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_print_dep_text_append_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_print_dep_text_get(&t), + "INFO: Disabling channel 1 (PRN 15)\n"); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgAgeCorrections.cc b/c/test/cpp/auto_check_sbp_navigation_MsgAgeCorrections.cc index 490024fc15..da814302cb 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgAgeCorrections.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgAgeCorrections.cc @@ -16,88 +16,588 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgAgeCorrections0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgAgeCorrections0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgAgeCorrections0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_navigation_MsgAgeCorrections0() { + assign(test_msg_.age, 30); + assign(test_msg_.tow, 100); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_age_corrections_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_age_corrections_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAgeCorrections, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_age_corrections_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAgeCorrections); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->age_corrections, + sizeof(msg->age_corrections)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_age_corrections_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.age_corrections, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAgeCorrections); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xcae9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 6; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_age_corrections_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_age_corrections_t &lesser, + const sbp_msg_age_corrections_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_age_corrections_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_age_corrections_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_age_corrections_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_age_corrections_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAgeCorrections, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgAgeCorrections, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgAgeCorrections, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgAgeCorrections, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_age_corrections_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgAgeCorrections0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_age_corrections_t test_msg_{}; + uint8_t encoded_frame_[6 + 8] = { 85, 16, 2, 66, 0, 6, 100, 0, 0, 0, 30, 0, 233, 202, }; + uint8_t encoded_payload_[6] = { + 100, 0, 0, 0, 30, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_age_corrections_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgAgeCorrections, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[6]; + uint8_t n_written; - sbp_msg_age_corrections_t test_msg{}; - test_msg.age = 30; - test_msg.tow = 100; + EXPECT_EQ(sbp_msg_age_corrections_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 6); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 6), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAgeCorrections, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 6); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 6), 0); +} - EXPECT_EQ(send_message(66, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[6]; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ(sbp_msg_age_corrections_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 6), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[6]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 6; i++) { + EXPECT_EQ( + sbp_msg_age_corrections_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_age_corrections_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_age_corrections_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 6); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.age, 30) - << "incorrect value for last_msg_.age, expected 30, is " << last_msg_.age; - EXPECT_EQ(last_msg_.tow, 100) - << "incorrect value for last_msg_.tow, expected 100, is " - << last_msg_.tow; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAgeCorrections, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 6); + EXPECT_EQ(msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_age_corrections_t msg{}; + + EXPECT_EQ(sbp_msg_age_corrections_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_age_corrections_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_age_corrections_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_age_corrections_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAgeCorrections, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_age_corrections_t lesser = info.test_msg; + sbp_msg_age_corrections_t greater = info.test_msg; + make_lesser_greater(lesser.age, greater.age); + comparison_tests(lesser, greater); + } + { + sbp_msg_age_corrections_t lesser = info.test_msg; + sbp_msg_age_corrections_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAgeCorrections); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_AGE_CORRECTIONS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_age_corrections_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_age_corrections_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.age_corrections, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.age_corrections, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[6]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 6); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 6), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_age_corrections_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 6); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAgeCorrections, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgAgeCorrections0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAgeCorrections, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEF.cc b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEF.cc index f267713d48..d3410947f1 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEF.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEF.cc @@ -16,521 +16,3024 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgBaselineECEF0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgBaselineECEF0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineECEF0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineECEF0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 14); + assign(test_msg_.tow, 326825000); + assign(test_msg_.x, -1154410); + assign(test_msg_.y, 1327294); + assign(test_msg_.z, 631798); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef, + sizeof(msg->baseline_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xbfdb; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ecef_t &lesser, + const sbp_msg_baseline_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEF0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 11, 2, 211, 136, 20, 40, 244, 122, 19, 150, 98, 238, 255, 190, 64, 20, 0, 246, 163, 9, 0, 0, 0, 14, 0, 219, 191, }; + uint8_t encoded_payload_[20] = { + 40, 244, 122, 19, 150, 98, 238, 255, 190, 64, + 20, 0, 246, 163, 9, 0, 0, 0, 14, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - sbp_msg_baseline_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 14; - test_msg.tow = 326825000; - test_msg.x = -1154410; - test_msg.y = 1327294; - test_msg.z = 631798; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 14) - << "incorrect value for last_msg_.n_sats, expected 14, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1154410) - << "incorrect value for last_msg_.x, expected -1154410, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1327294) - << "incorrect value for last_msg_.y, expected 1327294, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 631798) - << "incorrect value for last_msg_.z, expected 631798, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEF1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEF1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineECEF1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineECEF1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.x, -1154232); + assign(test_msg_.y, 1327551); + assign(test_msg_.z, 631434); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef, + sizeof(msg->baseline_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x4ef0; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ecef_t &lesser, + const sbp_msg_baseline_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEF1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_baseline_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 11, 2, 211, 136, 20, 16, 248, 122, 19, 72, 99, 238, 255, 191, 65, 20, 0, 138, 162, 9, 0, 0, 0, 15, 0, 240, 78, }; + uint8_t encoded_payload_[20] = { + 16, 248, 122, 19, 72, 99, 238, 255, 191, 65, + 20, 0, 138, 162, 9, 0, 0, 0, 15, 0, + }; +}; - sbp_msg_baseline_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.x = -1154232; - test_msg.y = 1327551; - test_msg.z = 631434; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1154232) - << "incorrect value for last_msg_.x, expected -1154232, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1327551) - << "incorrect value for last_msg_.y, expected 1327551, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 631434) - << "incorrect value for last_msg_.z, expected 631434, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEF2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEF2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEF2, Test) { - uint8_t encoded_frame[] = { - 85, 11, 2, 211, 136, 20, 248, 251, 122, 19, 41, 99, 238, 255, - 181, 65, 20, 0, 148, 161, 9, 0, 0, 0, 15, 0, 4, 132, - }; + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_baseline_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.x = -1154263; - test_msg.y = 1327541; - test_msg.z = 631188; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1154263) - << "incorrect value for last_msg_.x, expected -1154263, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1327541) - << "incorrect value for last_msg_.y, expected 1327541, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 631188) - << "incorrect value for last_msg_.z, expected 631188, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEF3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEF3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEF3, Test) { - uint8_t encoded_frame[] = { - 85, 11, 2, 211, 136, 20, 224, 255, 122, 19, 188, 97, 238, 255, - 81, 64, 20, 0, 65, 160, 9, 0, 0, 0, 15, 0, 67, 94, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_baseline_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326828000; - test_msg.x = -1154628; - test_msg.y = 1327185; - test_msg.z = 630849; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326828000) - << "incorrect value for last_msg_.tow, expected 326828000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1154628) - << "incorrect value for last_msg_.x, expected -1154628, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1327185) - << "incorrect value for last_msg_.y, expected 1327185, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 630849) - << "incorrect value for last_msg_.z, expected 630849, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEF4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEF4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEF4, Test) { - uint8_t encoded_frame[] = { - 85, 11, 2, 211, 136, 20, 200, 3, 123, 19, 189, 96, 238, 255, - 93, 63, 20, 0, 98, 159, 9, 0, 0, 0, 15, 0, 106, 94, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_baseline_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326829000; - test_msg.x = -1154883; - test_msg.y = 1326941; - test_msg.z = 630626; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326829000) - << "incorrect value for last_msg_.tow, expected 326829000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1154883) - << "incorrect value for last_msg_.x, expected -1154883, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1326941) - << "incorrect value for last_msg_.y, expected 1326941, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 630626) - << "incorrect value for last_msg_.z, expected 630626, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF"); } + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEF2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEF2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.x, -1154263); + assign(test_msg_.y, 1327541); + assign(test_msg_.z, 631188); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef, + sizeof(msg->baseline_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x8404; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_t &lesser, + const sbp_msg_baseline_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 11, 2, 211, 136, 20, 248, 251, 122, 19, 41, 99, 238, 255, + 181, 65, 20, 0, 148, 161, 9, 0, 0, 0, 15, 0, 4, 132, + }; + uint8_t encoded_payload_[20] = { + 248, 251, 122, 19, 41, 99, 238, 255, 181, 65, + 20, 0, 148, 161, 9, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEF3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEF3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326828000); + assign(test_msg_.x, -1154628); + assign(test_msg_.y, 1327185); + assign(test_msg_.z, 630849); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef, + sizeof(msg->baseline_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x5e43; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_t &lesser, + const sbp_msg_baseline_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 11, 2, 211, 136, 20, 224, 255, 122, 19, 188, 97, 238, 255, + 81, 64, 20, 0, 65, 160, 9, 0, 0, 0, 15, 0, 67, 94, + }; + uint8_t encoded_payload_[20] = { + 224, 255, 122, 19, 188, 97, 238, 255, 81, 64, + 20, 0, 65, 160, 9, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEF4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEF4() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326829000); + assign(test_msg_.x, -1154883); + assign(test_msg_.y, 1326941); + assign(test_msg_.z, 630626); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef, + sizeof(msg->baseline_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x5e6a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_t &lesser, + const sbp_msg_baseline_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 11, 2, 211, 136, 20, 200, 3, 123, 19, 189, 96, 238, 255, + 93, 63, 20, 0, 98, 159, 9, 0, 0, 0, 15, 0, 106, 94, + }; + uint8_t encoded_payload_[20] = { + 200, 3, 123, 19, 189, 96, 238, 255, 93, 63, + 20, 0, 98, 159, 9, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_baseline_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_t lesser = info.test_msg; + sbp_msg_baseline_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEF4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEFDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEFDepA.cc index c08eac33f6..f37144623b 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEFDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineECEFDepA.cc @@ -16,1117 +16,6824 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineECEFDepA0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.x, -53227); + assign(test_msg_.y, -35532); + assign(test_msg_.z, -76840); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8932; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 2, 2, 246, 215, 20, 20, 46, 39, 0, 21, 48, 255, 255, 52, 117, 255, 255, 216, 211, 254, 255, 0, 0, 9, 1, 50, 137, }; + uint8_t encoded_payload_[20] = { + 20, 46, 39, 0, 21, 48, 255, 255, 52, 117, + 255, 255, 216, 211, 254, 255, 0, 0, 9, 1, + }; +}; - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.x = -53227; - test_msg.y = -35532; - test_msg.z = -76840; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -53227) - << "incorrect value for last_msg_.x, expected -53227, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -35532) - << "incorrect value for last_msg_.y, expected -35532, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -76840) - << "incorrect value for last_msg_.z, expected -76840, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 246, 215, 20, 120, 46, 39, 0, 58, 49, 255, 255, - 49, 116, 255, 255, 134, 211, 254, 255, 0, 0, 9, 1, 227, 155, - }; + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.x = -52934; - test_msg.y = -35791; - test_msg.z = -76922; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -52934) - << "incorrect value for last_msg_.x, expected -52934, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -35791) - << "incorrect value for last_msg_.y, expected -35791, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -76922) - << "incorrect value for last_msg_.z, expected -76922, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 246, 215, 20, 220, 46, 39, 0, 97, 50, 255, 255, - 47, 115, 255, 255, 52, 211, 254, 255, 0, 0, 9, 1, 61, 126, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.x = -52639; - test_msg.y = -36049; - test_msg.z = -77004; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -52639) - << "incorrect value for last_msg_.x, expected -52639, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -36049) - << "incorrect value for last_msg_.y, expected -36049, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -77004) - << "incorrect value for last_msg_.z, expected -77004, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 246, 215, 20, 64, 47, 39, 0, 136, 51, 255, 255, - 45, 114, 255, 255, 228, 210, 254, 255, 0, 0, 9, 1, 200, 79, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2568000; - test_msg.x = -52344; - test_msg.y = -36307; - test_msg.z = -77084; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568000) - << "incorrect value for last_msg_.tow, expected 2568000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -52344) - << "incorrect value for last_msg_.x, expected -52344, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -36307) - << "incorrect value for last_msg_.y, expected -36307, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -77084) - << "incorrect value for last_msg_.z, expected -77084, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 246, 215, 20, 164, 47, 39, 0, 176, 52, 255, 255, - 44, 113, 255, 255, 149, 210, 254, 255, 0, 0, 9, 1, 104, 24, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2568100; - test_msg.x = -52048; - test_msg.y = -36564; - test_msg.z = -77163; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568100) - << "incorrect value for last_msg_.tow, expected 2568100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -52048) - << "incorrect value for last_msg_.x, expected -52048, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -36564) - << "incorrect value for last_msg_.y, expected -36564, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -77163) - << "incorrect value for last_msg_.z, expected -77163, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 156, 21, 69, 24, 169, 231, 255, 255, - 102, 208, 255, 255, 251, 28, 0, 0, 0, 0, 6, 0, 146, 168, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407180700; - test_msg.x = -6231; - test_msg.y = -12186; - test_msg.z = 7419; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180700) - << "incorrect value for last_msg_.tow, expected 407180700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -6231) - << "incorrect value for last_msg_.x, expected -6231, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -12186) - << "incorrect value for last_msg_.y, expected -12186, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 7419) - << "incorrect value for last_msg_.z, expected 7419, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA1 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineECEFDepA1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.x, -52934); + assign(test_msg_.y, -35791); + assign(test_msg_.z, -76922); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 0, 22, 69, 24, 169, 231, 255, 255, - 103, 208, 255, 255, 252, 28, 0, 0, 0, 0, 6, 0, 34, 116, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407180800; - test_msg.x = -6231; - test_msg.y = -12185; - test_msg.z = 7420; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180800) - << "incorrect value for last_msg_.tow, expected 407180800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -6231) - << "incorrect value for last_msg_.x, expected -6231, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -12185) - << "incorrect value for last_msg_.y, expected -12185, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 7420) - << "incorrect value for last_msg_.z, expected 7420, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 100, 22, 69, 24, 30, 224, 255, 255, - 192, 183, 255, 255, 239, 53, 0, 0, 0, 0, 6, 0, 225, 15, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407180900; - test_msg.x = -8162; - test_msg.y = -18496; - test_msg.z = 13807; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180900) - << "incorrect value for last_msg_.tow, expected 407180900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -8162) - << "incorrect value for last_msg_.x, expected -8162, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -18496) - << "incorrect value for last_msg_.y, expected -18496, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 13807) - << "incorrect value for last_msg_.z, expected 13807, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 200, 22, 69, 24, 28, 224, 255, 255, - 191, 183, 255, 255, 242, 53, 0, 0, 0, 0, 6, 0, 35, 100, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407181000; - test_msg.x = -8164; - test_msg.y = -18497; - test_msg.z = 13810; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181000) - << "incorrect value for last_msg_.tow, expected 407181000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -8164) - << "incorrect value for last_msg_.x, expected -8164, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -18497) - << "incorrect value for last_msg_.y, expected -18497, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 13810) - << "incorrect value for last_msg_.z, expected 13810, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 44, 23, 69, 24, 24, 227, 255, 255, - 25, 195, 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, 66, 66, + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407181100; - test_msg.x = -7400; - test_msg.y = -15591; - test_msg.z = 15257; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181100) - << "incorrect value for last_msg_.tow, expected 407181100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -7400) - << "incorrect value for last_msg_.x, expected -7400, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -15591) - << "incorrect value for last_msg_.y, expected -15591, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 15257) - << "incorrect value for last_msg_.z, expected 15257, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgBaselineECEFDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineECEFDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x9be3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineECEFDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 2, 2, 195, 4, 20, 144, 23, 69, 24, 23, 227, 255, 255, - 25, 195, 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, 35, 135, + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 246, 215, 20, 120, 46, 39, 0, 58, 49, 255, 255, + 49, 116, 255, 255, 134, 211, 254, 255, 0, 0, 9, 1, 227, 155, + }; + uint8_t encoded_payload_[20] = { + 120, 46, 39, 0, 58, 49, 255, 255, 49, 116, + 255, 255, 134, 211, 254, 255, 0, 0, 9, 1, }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - sbp_msg_baseline_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 6; - test_msg.tow = 407181200; - test_msg.x = -7401; - test_msg.y = -15591; - test_msg.z = 15257; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181200) - << "incorrect value for last_msg_.tow, expected 407181200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -7401) - << "incorrect value for last_msg_.x, expected -7401, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -15591) - << "incorrect value for last_msg_.y, expected -15591, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 15257) - << "incorrect value for last_msg_.z, expected 15257, is " << last_msg_.z; + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA2 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.x, -52639); + assign(test_msg_.y, -36049); + assign(test_msg_.z, -77004); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x7e3d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 246, 215, 20, 220, 46, 39, 0, 97, 50, 255, 255, + 47, 115, 255, 255, 52, 211, 254, 255, 0, 0, 9, 1, 61, 126, + }; + uint8_t encoded_payload_[20] = { + 220, 46, 39, 0, 97, 50, 255, 255, 47, 115, + 255, 255, 52, 211, 254, 255, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA3 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568000); + assign(test_msg_.x, -52344); + assign(test_msg_.y, -36307); + assign(test_msg_.z, -77084); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x4fc8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 246, 215, 20, 64, 47, 39, 0, 136, 51, 255, 255, + 45, 114, 255, 255, 228, 210, 254, 255, 0, 0, 9, 1, 200, 79, + }; + uint8_t encoded_payload_[20] = { + 64, 47, 39, 0, 136, 51, 255, 255, 45, 114, + 255, 255, 228, 210, 254, 255, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA4 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA4() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568100); + assign(test_msg_.x, -52048); + assign(test_msg_.y, -36564); + assign(test_msg_.z, -77163); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x1868; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 246, 215, 20, 164, 47, 39, 0, 176, 52, 255, 255, + 44, 113, 255, 255, 149, 210, 254, 255, 0, 0, 9, 1, 104, 24, + }; + uint8_t encoded_payload_[20] = { + 164, 47, 39, 0, 176, 52, 255, 255, 44, 113, + 255, 255, 149, 210, 254, 255, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA5 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA5() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180700); + assign(test_msg_.x, -6231); + assign(test_msg_.y, -12186); + assign(test_msg_.z, 7419); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xa892; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 156, 21, 69, 24, 169, 231, 255, 255, + 102, 208, 255, 255, 251, 28, 0, 0, 0, 0, 6, 0, 146, 168, + }; + uint8_t encoded_payload_[20] = { + 156, 21, 69, 24, 169, 231, 255, 255, 102, 208, + 255, 255, 251, 28, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA6 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA6() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180800); + assign(test_msg_.x, -6231); + assign(test_msg_.y, -12185); + assign(test_msg_.z, 7420); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x7422; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 0, 22, 69, 24, 169, 231, 255, 255, + 103, 208, 255, 255, 252, 28, 0, 0, 0, 0, 6, 0, 34, 116, + }; + uint8_t encoded_payload_[20] = { + 0, 22, 69, 24, 169, 231, 255, 255, 103, 208, + 255, 255, 252, 28, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA7 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA7() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180900); + assign(test_msg_.x, -8162); + assign(test_msg_.y, -18496); + assign(test_msg_.z, 13807); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xfe1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 100, 22, 69, 24, 30, 224, 255, 255, + 192, 183, 255, 255, 239, 53, 0, 0, 0, 0, 6, 0, 225, 15, + }; + uint8_t encoded_payload_[20] = { + 100, 22, 69, 24, 30, 224, 255, 255, 192, 183, + 255, 255, 239, 53, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA8 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA8() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181000); + assign(test_msg_.x, -8164); + assign(test_msg_.y, -18497); + assign(test_msg_.z, 13810); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6423; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 200, 22, 69, 24, 28, 224, 255, 255, + 191, 183, 255, 255, 242, 53, 0, 0, 0, 0, 6, 0, 35, 100, + }; + uint8_t encoded_payload_[20] = { + 200, 22, 69, 24, 28, 224, 255, 255, 191, 183, + 255, 255, 242, 53, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA9 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA9() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181100); + assign(test_msg_.x, -7400); + assign(test_msg_.y, -15591); + assign(test_msg_.z, 15257); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x4242; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 44, 23, 69, 24, 24, 227, 255, 255, + 25, 195, 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, 66, 66, + }; + uint8_t encoded_payload_[20] = { + 44, 23, 69, 24, 24, 227, 255, 255, 25, 195, + 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineECEFDepA10 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineECEFDepA10() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181200); + assign(test_msg_.x, -7401); + assign(test_msg_.y, -15591); + assign(test_msg_.z, 15257); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ecef_dep_a, + sizeof(msg->baseline_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x8723; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ecef_dep_a_t &lesser, + const sbp_msg_baseline_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineEcefDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 2, 2, 195, 4, 20, 144, 23, 69, 24, 23, 227, 255, 255, + 25, 195, 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, 35, 135, + }; + uint8_t encoded_payload_[20] = { + 144, 23, 69, 24, 23, 227, 255, 255, 25, 195, + 255, 255, 153, 59, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_baseline_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ecef_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineECEFDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNED.cc b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNED.cc index 023c4b323a..155a18d9b7 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNED.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNED.cc @@ -16,536 +16,3049 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgBaselineNED0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgBaselineNED0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineNED0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineNED0() { + assign(test_msg_.d, 32153); + assign(test_msg_.e, -1681229); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 816073); + assign(test_msg_.n_sats, 14); + assign(test_msg_.tow, 326825000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNed, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned, + sizeof(msg->baseline_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x46e2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ned_t &lesser, + const sbp_msg_baseline_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNED0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 12, 2, 211, 136, 22, 40, 244, 122, 19, 201, 115, 12, 0, 179, 88, 230, 255, 153, 125, 0, 0, 0, 0, 0, 0, 14, 0, 226, 70, }; + uint8_t encoded_payload_[22] = { + 40, 244, 122, 19, 201, 115, 12, 0, 179, 88, 230, + 255, 153, 125, 0, 0, 0, 0, 0, 0, 14, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNed, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_baseline_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNed); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_baseline_ned_t test_msg{}; - test_msg.d = 32153; - test_msg.e = -1681229; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 816073; - test_msg.n_sats = 14; - test_msg.tow = 326825000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 32153) - << "incorrect value for last_msg_.d, expected 32153, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1681229) - << "incorrect value for last_msg_.e, expected -1681229, is " - << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 816073) - << "incorrect value for last_msg_.n, expected 816073, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 14) - << "incorrect value for last_msg_.n_sats, expected 14, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNED1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNed, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNed, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNED1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineNED1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineNED1() { + assign(test_msg_.d, 32622); + assign(test_msg_.e, -1681214); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 815970); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNed, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned, + sizeof(msg->baseline_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x5d45; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ned_t &lesser, + const sbp_msg_baseline_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNED1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 12, 2, 211, 136, 22, 16, 248, 122, 19, 98, 115, 12, 0, 194, 88, 230, 255, 110, 127, 0, 0, 0, 0, 0, 0, 15, 0, 69, 93, }; + uint8_t encoded_payload_[22] = { + 16, 248, 122, 19, 98, 115, 12, 0, 194, 88, 230, + 255, 110, 127, 0, 0, 0, 0, 0, 0, 15, 0, + }; +}; - sbp_msg_baseline_ned_t test_msg{}; - test_msg.d = 32622; - test_msg.e = -1681214; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 815970; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 32622) - << "incorrect value for last_msg_.d, expected 32622, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1681214) - << "incorrect value for last_msg_.e, expected -1681214, is " - << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 815970) - << "incorrect value for last_msg_.n, expected 815970, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNED2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNED2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNed, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNED2, Test) { - uint8_t encoded_frame[] = { - 85, 12, 2, 211, 136, 22, 248, 251, 122, 19, 143, 114, 12, 0, 173, - 88, 230, 255, 238, 127, 0, 0, 0, 0, 0, 0, 15, 0, 210, 169, - }; + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_baseline_ned_t test_msg{}; - test_msg.d = 32750; - test_msg.e = -1681235; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 815759; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 32750) - << "incorrect value for last_msg_.d, expected 32750, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1681235) - << "incorrect value for last_msg_.e, expected -1681235, is " - << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 815759) - << "incorrect value for last_msg_.n, expected 815759, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNED3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNED3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_baseline_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNED3, Test) { - uint8_t encoded_frame[] = { - 85, 12, 2, 211, 136, 22, 224, 255, 122, 19, 86, 112, 12, 0, 51, - 88, 230, 255, 47, 127, 0, 0, 0, 0, 0, 0, 15, 0, 135, 107, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_baseline_ned_t test_msg{}; - test_msg.d = 32559; - test_msg.e = -1681357; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 815190; - test_msg.n_sats = 15; - test_msg.tow = 326828000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 32559) - << "incorrect value for last_msg_.d, expected 32559, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1681357) - << "incorrect value for last_msg_.e, expected -1681357, is " - << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 815190) - << "incorrect value for last_msg_.n, expected 815190, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326828000) - << "incorrect value for last_msg_.tow, expected 326828000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNED4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNED4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNED4, Test) { - uint8_t encoded_frame[] = { - 85, 12, 2, 211, 136, 22, 200, 3, 123, 19, 214, 110, 12, 0, 220, - 87, 230, 255, 165, 126, 0, 0, 0, 0, 0, 0, 15, 0, 190, 80, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} - sbp_msg_baseline_ned_t test_msg{}; - test_msg.d = 32421; - test_msg.e = -1681444; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 814806; - test_msg.n_sats = 15; - test_msg.tow = 326829000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 32421) - << "incorrect value for last_msg_.d, expected 32421, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1681444) - << "incorrect value for last_msg_.e, expected -1681444, is " - << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 814806) - << "incorrect value for last_msg_.n, expected 814806, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326829000) - << "incorrect value for last_msg_.tow, expected 326829000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNed); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED"); } + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNed, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNed, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNED2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNED2() { + assign(test_msg_.d, 32750); + assign(test_msg_.e, -1681235); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 815759); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNed, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned, + sizeof(msg->baseline_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xa9d2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_t &lesser, + const sbp_msg_baseline_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 12, 2, 211, 136, 22, 248, 251, 122, 19, 143, 114, 12, 0, 173, + 88, 230, 255, 238, 127, 0, 0, 0, 0, 0, 0, 15, 0, 210, 169, + }; + uint8_t encoded_payload_[22] = { + 248, 251, 122, 19, 143, 114, 12, 0, 173, 88, 230, + 255, 238, 127, 0, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNed, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_baseline_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNed); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNed, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNed, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNED3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNED3() { + assign(test_msg_.d, 32559); + assign(test_msg_.e, -1681357); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 815190); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326828000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNed, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned, + sizeof(msg->baseline_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x6b87; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_t &lesser, + const sbp_msg_baseline_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 12, 2, 211, 136, 22, 224, 255, 122, 19, 86, 112, 12, 0, 51, + 88, 230, 255, 47, 127, 0, 0, 0, 0, 0, 0, 15, 0, 135, 107, + }; + uint8_t encoded_payload_[22] = { + 224, 255, 122, 19, 86, 112, 12, 0, 51, 88, 230, + 255, 47, 127, 0, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNed, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_baseline_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNed); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNed, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNed, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNED4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNED4() { + assign(test_msg_.d, 32421); + assign(test_msg_.e, -1681444); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 814806); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326829000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNed, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned, + sizeof(msg->baseline_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x50be; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_t &lesser, + const sbp_msg_baseline_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBaselineNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 12, 2, 211, 136, 22, 200, 3, 123, 19, 214, 110, 12, 0, 220, + 87, 230, 255, 165, 126, 0, 0, 0, 0, 0, 0, 15, 0, 190, 80, + }; + uint8_t encoded_payload_[22] = { + 200, 3, 123, 19, 214, 110, 12, 0, 220, 87, 230, + 255, 165, 126, 0, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBaselineNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNed, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_baseline_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_baseline_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_t lesser = info.test_msg; + sbp_msg_baseline_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNed); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.baseline_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.baseline_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNed, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNED4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNed, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNEDDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNEDDepA.cc index 09a39a63d7..219af7a263 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNEDDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgBaselineNEDDepA.cc @@ -16,1161 +16,6849 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineNEDDepA0() { + assign(test_msg_.d, 0); + assign(test_msg_.e, -26134); + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -96525); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xc15d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 3, 2, 246, 215, 22, 20, 46, 39, 0, 243, 134, 254, 255, 234, 153, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 93, 193, }; + uint8_t encoded_payload_[22] = { + 20, 46, 39, 0, 243, 134, 254, 255, 234, 153, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, + }; +}; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = -26134; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.n = -96525; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -26134) - << "incorrect value for last_msg_.e, expected -26134, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -96525) - << "incorrect value for last_msg_.n, expected -96525, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 246, 215, 22, 120, 46, 39, 0, 139, 134, 254, 255, 109, - 155, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 38, 39, - }; + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = -25747; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.n = -96629; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -25747) - << "incorrect value for last_msg_.e, expected -25747, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -96629) - << "incorrect value for last_msg_.n, expected -96629, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 246, 215, 22, 220, 46, 39, 0, 37, 134, 254, 255, 240, - 156, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 58, 133, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = -25360; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.n = -96731; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -25360) - << "incorrect value for last_msg_.e, expected -25360, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -96731) - << "incorrect value for last_msg_.n, expected -96731, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 246, 215, 22, 64, 47, 39, 0, 193, 133, 254, 255, 115, - 158, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 56, 214, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = -24973; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.n = -96831; - test_msg.n_sats = 9; - test_msg.tow = 2568000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -24973) - << "incorrect value for last_msg_.e, expected -24973, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -96831) - << "incorrect value for last_msg_.n, expected -96831, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568000) - << "incorrect value for last_msg_.tow, expected 2568000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 246, 215, 22, 164, 47, 39, 0, 93, 133, 254, 255, 246, - 159, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 234, 244, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = -24586; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.n = -96931; - test_msg.n_sats = 9; - test_msg.tow = 2568100; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -24586) - << "incorrect value for last_msg_.e, expected -24586, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -96931) - << "incorrect value for last_msg_.n, expected -96931, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568100) - << "incorrect value for last_msg_.tow, expected 2568100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 156, 21, 69, 24, 130, 246, 255, 255, 241, - 4, 0, 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, 250, 21, - }; +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -15325; - test_msg.e = 1265; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -2430; - test_msg.n_sats = 6; - test_msg.tow = 407180700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -15325) - << "incorrect value for last_msg_.d, expected -15325, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 1265) - << "incorrect value for last_msg_.e, expected 1265, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -2430) - << "incorrect value for last_msg_.n, expected -2430, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180700) - << "incorrect value for last_msg_.tow, expected 407180700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA1 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgBaselineNEDDepA1() { + assign(test_msg_.d, 0); + assign(test_msg_.e, -25747); + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -96629); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.v_accuracy, 0); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 0, 22, 69, 24, 130, 246, 255, 255, 241, - 4, 0, 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, 240, 133, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -15325; - test_msg.e = 1265; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -2430; - test_msg.n_sats = 6; - test_msg.tow = 407180800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -15325) - << "incorrect value for last_msg_.d, expected -15325, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 1265) - << "incorrect value for last_msg_.e, expected 1265, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -2430) - << "incorrect value for last_msg_.n, expected -2430, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180800) - << "incorrect value for last_msg_.tow, expected 407180800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 100, 22, 69, 24, 32, 251, 255, 255, 199, - 11, 0, 0, 57, 161, 255, 255, 0, 0, 0, 0, 6, 0, 12, 181, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -24263; - test_msg.e = 3015; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -1248; - test_msg.n_sats = 6; - test_msg.tow = 407180900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -24263) - << "incorrect value for last_msg_.d, expected -24263, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3015) - << "incorrect value for last_msg_.e, expected 3015, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -1248) - << "incorrect value for last_msg_.n, expected -1248, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407180900) - << "incorrect value for last_msg_.tow, expected 407180900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 200, 22, 69, 24, 33, 251, 255, 255, 199, - 11, 0, 0, 54, 161, 255, 255, 0, 0, 0, 0, 6, 0, 86, 58, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -24266; - test_msg.e = 3015; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -1247; - test_msg.n_sats = 6; - test_msg.tow = 407181000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -24266) - << "incorrect value for last_msg_.d, expected -24266, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3015) - << "incorrect value for last_msg_.e, expected 3015, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -1247) - << "incorrect value for last_msg_.n, expected -1247, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181000) - << "incorrect value for last_msg_.tow, expected 407181000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 44, 23, 69, 24, 110, 6, 0, 0, 55, - 8, 0, 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, 51, 249, + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -22880; - test_msg.e = 2103; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 1646; - test_msg.n_sats = 6; - test_msg.tow = 407181100; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -22880) - << "incorrect value for last_msg_.d, expected -22880, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 2103) - << "incorrect value for last_msg_.e, expected 2103, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 1646) - << "incorrect value for last_msg_.n, expected 1646, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181100) - << "incorrect value for last_msg_.tow, expected 407181100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgBaselineNEDDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgBaselineNEDDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x2726; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_baseline_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_baseline_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgBaselineNEDDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 3, 2, 195, 4, 22, 144, 23, 69, 24, 110, 6, 0, 0, 54, - 8, 0, 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, 206, 22, + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 246, 215, 22, 120, 46, 39, 0, 139, 134, 254, 255, 109, + 155, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 38, 39, }; + uint8_t encoded_payload_[22] = { + 120, 46, 39, 0, 139, 134, 254, 255, 109, 155, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; - sbp_msg_baseline_ned_dep_a_t test_msg{}; - test_msg.d = -22880; - test_msg.e = 2102; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 1646; - test_msg.n_sats = 6; - test_msg.tow = 407181200; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -22880) - << "incorrect value for last_msg_.d, expected -22880, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 2102) - << "incorrect value for last_msg_.e, expected 2102, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 1646) - << "incorrect value for last_msg_.n, expected 1646, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 6) - << "incorrect value for last_msg_.n_sats, expected 6, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407181200) - << "incorrect value for last_msg_.tow, expected 407181200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA2 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA2() { + assign(test_msg_.d, 0); + assign(test_msg_.e, -25360); + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -96731); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x853a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 246, 215, 22, 220, 46, 39, 0, 37, 134, 254, 255, 240, + 156, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 58, 133, + }; + uint8_t encoded_payload_[22] = { + 220, 46, 39, 0, 37, 134, 254, 255, 240, 156, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA3 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA3() { + assign(test_msg_.d, 0); + assign(test_msg_.e, -24973); + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -96831); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xd638; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 246, 215, 22, 64, 47, 39, 0, 193, 133, 254, 255, 115, + 158, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 56, 214, + }; + uint8_t encoded_payload_[22] = { + 64, 47, 39, 0, 193, 133, 254, 255, 115, 158, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA4 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA4() { + assign(test_msg_.d, 0); + assign(test_msg_.e, -24586); + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -96931); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568100); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xf4ea; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 246, 215, 22, 164, 47, 39, 0, 93, 133, 254, 255, 246, + 159, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, 234, 244, + }; + uint8_t encoded_payload_[22] = { + 164, 47, 39, 0, 93, 133, 254, 255, 246, 159, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA5 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA5() { + assign(test_msg_.d, -15325); + assign(test_msg_.e, 1265); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -2430); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x15fa; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 156, 21, 69, 24, 130, 246, 255, 255, 241, + 4, 0, 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, 250, 21, + }; + uint8_t encoded_payload_[22] = { + 156, 21, 69, 24, 130, 246, 255, 255, 241, 4, 0, + 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA6 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA6() { + assign(test_msg_.d, -15325); + assign(test_msg_.e, 1265); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -2430); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180800); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x85f0; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 0, 22, 69, 24, 130, 246, 255, 255, 241, + 4, 0, 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, 240, 133, + }; + uint8_t encoded_payload_[22] = { + 0, 22, 69, 24, 130, 246, 255, 255, 241, 4, 0, + 0, 35, 196, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA7 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA7() { + assign(test_msg_.d, -24263); + assign(test_msg_.e, 3015); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -1248); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407180900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xb50c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 100, 22, 69, 24, 32, 251, 255, 255, 199, + 11, 0, 0, 57, 161, 255, 255, 0, 0, 0, 0, 6, 0, 12, 181, + }; + uint8_t encoded_payload_[22] = { + 100, 22, 69, 24, 32, 251, 255, 255, 199, 11, 0, + 0, 57, 161, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA8 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA8() { + assign(test_msg_.d, -24266); + assign(test_msg_.e, 3015); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -1247); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x3a56; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 200, 22, 69, 24, 33, 251, 255, 255, 199, + 11, 0, 0, 54, 161, 255, 255, 0, 0, 0, 0, 6, 0, 86, 58, + }; + uint8_t encoded_payload_[22] = { + 200, 22, 69, 24, 33, 251, 255, 255, 199, 11, 0, + 0, 54, 161, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA9 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA9() { + assign(test_msg_.d, -22880); + assign(test_msg_.e, 2103); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 1646); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181100); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xf933; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 44, 23, 69, 24, 110, 6, 0, 0, 55, + 8, 0, 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, 51, 249, + }; + uint8_t encoded_payload_[22] = { + 44, 23, 69, 24, 110, 6, 0, 0, 55, 8, 0, + 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgBaselineNEDDepA10 + : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgBaselineNEDDepA10() { + assign(test_msg_.d, -22880); + assign(test_msg_.e, 2102); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 1646); + assign(test_msg_.n_sats, 6); + assign(test_msg_.tow, 407181200); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_baseline_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBaselineNedDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_baseline_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBaselineNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->baseline_ned_dep_a, + sizeof(msg->baseline_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_baseline_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.baseline_ned_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBaselineNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x16ce; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_baseline_ned_dep_a_t &lesser, + const sbp_msg_baseline_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_baseline_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_baseline_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgBaselineNedDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_baseline_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 3, 2, 195, 4, 22, 144, 23, 69, 24, 110, 6, 0, 0, 54, + 8, 0, 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, 206, 22, + }; + uint8_t encoded_payload_[22] = { + 144, 23, 69, 24, 110, 6, 0, 0, 54, 8, 0, + 0, 160, 166, 255, 255, 0, 0, 0, 0, 6, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBaselineNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ( + sbp_msg_baseline_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBaselineNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_baseline_ned_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBaselineNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_baseline_ned_dep_a_t lesser = info.test_msg; + sbp_msg_baseline_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBaselineNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASELINE_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_baseline_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_baseline_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.baseline_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.baseline_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_baseline_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBaselineNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgBaselineNEDDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBaselineNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgDops.cc b/c/test/cpp/auto_check_sbp_navigation_MsgDops.cc index 461053d52c..058bf2b366 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgDops.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgDops.cc @@ -16,109 +16,596 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgDops0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgDops0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgDops0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgDops0() { + assign(test_msg_.flags, 0); + assign(test_msg_.gdop, 2); + assign(test_msg_.hdop, 5); + assign(test_msg_.pdop, 6); + assign(test_msg_.tdop, 5); + assign(test_msg_.tow, 100); + assign(test_msg_.vdop, 5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDops, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDops); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops, sizeof(msg->dops)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDops); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x4f4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 15; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_dops_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_dops_t &lesser, + const sbp_msg_dops_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDops, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDops, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgDops, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgDops, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgDops0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_t test_msg_{}; + uint8_t encoded_frame_[15 + 8] = { 85, 8, 2, 66, 0, 15, 100, 0, 0, 0, 2, 0, 6, 0, 5, 0, 5, 0, 5, 0, 0, 244, 4, }; + uint8_t encoded_payload_[15] = { + 100, 0, 0, 0, 2, 0, 6, 0, 5, 0, 5, 0, 5, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDops, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_dops_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDops, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[15]; - sbp_msg_dops_t test_msg{}; - test_msg.flags = 0; - test_msg.gdop = 2; - test_msg.hdop = 5; - test_msg.pdop = 6; - test_msg.tdop = 5; - test_msg.tow = 100; - test_msg.vdop = 5; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.gdop, 2) - << "incorrect value for last_msg_.gdop, expected 2, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 5) - << "incorrect value for last_msg_.hdop, expected 5, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 6) - << "incorrect value for last_msg_.pdop, expected 6, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 5) - << "incorrect value for last_msg_.tdop, expected 5, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 100) - << "incorrect value for last_msg_.tow, expected 100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 5) - << "incorrect value for last_msg_.vdop, expected 5, is " - << last_msg_.vdop; + EXPECT_EQ(sbp_msg_dops_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); } +TEST_F(Testauto_check_sbp_navigation_MsgDops0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + + for (uint8_t i = 0; i < 15; i++) { + EXPECT_EQ(sbp_msg_dops_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDops, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_t msg{}; + + EXPECT_EQ(sbp_msg_dops_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDops0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_dops_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDops, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_t lesser = info.test_msg; + sbp_msg_dops_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDops); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_DOPS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDops, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDops0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDops, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgDopsDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgDopsDepA.cc index ee747da7a9..7298ac6580 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgDopsDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgDopsDepA.cc @@ -16,905 +16,5252 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgDopsDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgDopsDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgDopsDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgDopsDepA0() { + assign(test_msg_.gdop, 180); + assign(test_msg_.hdop, 160); + assign(test_msg_.pdop, 190); + assign(test_msg_.tdop, 170); + assign(test_msg_.tow, 2568200); + assign(test_msg_.vdop, 150); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xaa79; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { 85, 6, 2, 246, 215, 14, 8, 48, 39, 0, 180, 0, 190, 0, 170, 0, 160, 0, 150, 0, 121, 170, }; + uint8_t encoded_payload_[14] = { + 8, 48, 39, 0, 180, 0, 190, 0, 170, 0, 160, 0, 150, 0, + }; +}; - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 180; - test_msg.hdop = 160; - test_msg.pdop = 190; - test_msg.tdop = 170; - test_msg.tow = 2568200; - test_msg.vdop = 150; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 180) - << "incorrect value for last_msg_.gdop, expected 180, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 160) - << "incorrect value for last_msg_.hdop, expected 160, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 190) - << "incorrect value for last_msg_.pdop, expected 190, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 170) - << "incorrect value for last_msg_.tdop, expected 170, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 2568200) - << "incorrect value for last_msg_.tow, expected 2568200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 150) - << "incorrect value for last_msg_.vdop, expected 150, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 246, 215, 14, 240, 51, 39, 0, 180, - 0, 190, 0, 170, 0, 160, 0, 150, 0, 78, 169, - }; + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 180; - test_msg.hdop = 160; - test_msg.pdop = 190; - test_msg.tdop = 170; - test_msg.tow = 2569200; - test_msg.vdop = 150; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 180) - << "incorrect value for last_msg_.gdop, expected 180, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 160) - << "incorrect value for last_msg_.hdop, expected 160, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 190) - << "incorrect value for last_msg_.pdop, expected 190, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 170) - << "incorrect value for last_msg_.tdop, expected 170, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 2569200) - << "incorrect value for last_msg_.tow, expected 2569200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 150) - << "incorrect value for last_msg_.vdop, expected 150, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 246, 215, 14, 216, 55, 39, 0, 180, - 0, 190, 0, 170, 0, 160, 0, 150, 0, 71, 218, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 180; - test_msg.hdop = 160; - test_msg.pdop = 190; - test_msg.tdop = 170; - test_msg.tow = 2570200; - test_msg.vdop = 150; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 180) - << "incorrect value for last_msg_.gdop, expected 180, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 160) - << "incorrect value for last_msg_.hdop, expected 160, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 190) - << "incorrect value for last_msg_.pdop, expected 190, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 170) - << "incorrect value for last_msg_.tdop, expected 170, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 2570200) - << "incorrect value for last_msg_.tow, expected 2570200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 150) - << "incorrect value for last_msg_.vdop, expected 150, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 212, 157, 67, 24, 247, - 0, 215, 0, 123, 0, 17, 1, 44, 0, 206, 21, - }; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 247; - test_msg.hdop = 273; - test_msg.pdop = 215; - test_msg.tdop = 123; - test_msg.tow = 407084500; - test_msg.vdop = 44; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 247) - << "incorrect value for last_msg_.gdop, expected 247, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 273) - << "incorrect value for last_msg_.hdop, expected 273, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 215) - << "incorrect value for last_msg_.pdop, expected 215, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 123) - << "incorrect value for last_msg_.tdop, expected 123, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 44) - << "incorrect value for last_msg_.vdop, expected 44, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 0, 0, 0, 0, 255, - 255, 255, 255, 0, 0, 0, 0, 0, 0, 146, 12, - }; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 65535; - test_msg.hdop = 0; - test_msg.pdop = 65535; - test_msg.tdop = 0; - test_msg.tow = 0; - test_msg.vdop = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 65535) - << "incorrect value for last_msg_.gdop, expected 65535, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 0) - << "incorrect value for last_msg_.hdop, expected 0, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 65535) - << "incorrect value for last_msg_.pdop, expected 65535, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 0) - << "incorrect value for last_msg_.tdop, expected 0, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 0) - << "incorrect value for last_msg_.tow, expected 0, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 0) - << "incorrect value for last_msg_.vdop, expected 0, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 128, 165, 68, 24, 92, - 1, 56, 1, 155, 0, 125, 2, 113, 0, 129, 93, - }; +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 348; - test_msg.hdop = 637; - test_msg.pdop = 312; - test_msg.tdop = 155; - test_msg.tow = 407152000; - test_msg.vdop = 113; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 348) - << "incorrect value for last_msg_.gdop, expected 348, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 637) - << "incorrect value for last_msg_.hdop, expected 637, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 312) - << "incorrect value for last_msg_.pdop, expected 312, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 155) - << "incorrect value for last_msg_.tdop, expected 155, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 407152000) - << "incorrect value for last_msg_.tow, expected 407152000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 113) - << "incorrect value for last_msg_.vdop, expected 113, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgDopsDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgDopsDepA1() { + assign(test_msg_.gdop, 180); + assign(test_msg_.hdop, 160); + assign(test_msg_.pdop, 190); + assign(test_msg_.tdop, 170); + assign(test_msg_.tow, 2569200); + assign(test_msg_.vdop, 150); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 104, 169, 68, 24, 92, - 1, 55, 1, 155, 0, 125, 2, 113, 0, 209, 128, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 348; - test_msg.hdop = 637; - test_msg.pdop = 311; - test_msg.tdop = 155; - test_msg.tow = 407153000; - test_msg.vdop = 113; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 348) - << "incorrect value for last_msg_.gdop, expected 348, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 637) - << "incorrect value for last_msg_.hdop, expected 637, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 311) - << "incorrect value for last_msg_.pdop, expected 311, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 155) - << "incorrect value for last_msg_.tdop, expected 155, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 407153000) - << "incorrect value for last_msg_.tow, expected 407153000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 113) - << "incorrect value for last_msg_.vdop, expected 113, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 80, 173, 68, 24, 92, - 1, 55, 1, 155, 0, 125, 2, 112, 0, 30, 6, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 348; - test_msg.hdop = 637; - test_msg.pdop = 311; - test_msg.tdop = 155; - test_msg.tow = 407154000; - test_msg.vdop = 112; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 348) - << "incorrect value for last_msg_.gdop, expected 348, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 637) - << "incorrect value for last_msg_.hdop, expected 637, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 311) - << "incorrect value for last_msg_.pdop, expected 311, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 155) - << "incorrect value for last_msg_.tdop, expected 155, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 407154000) - << "incorrect value for last_msg_.tow, expected 407154000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 112) - << "incorrect value for last_msg_.vdop, expected 112, is " - << last_msg_.vdop; -} -class Test_auto_check_sbp_navigation_MsgDopsDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgDopsDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xa94e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dops_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_dops_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgDopsDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 6, 2, 195, 4, 14, 56, 177, 68, 24, 92, - 1, 55, 1, 155, 0, 125, 2, 112, 0, 70, 67, + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 246, 215, 14, 240, 51, 39, 0, 180, + 0, 190, 0, 170, 0, 160, 0, 150, 0, 78, 169, }; + uint8_t encoded_payload_[14] = { + 240, 51, 39, 0, 180, 0, 190, 0, 170, 0, 160, 0, 150, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; - sbp_msg_dops_dep_a_t test_msg{}; - test_msg.gdop = 348; - test_msg.hdop = 637; - test_msg.pdop = 311; - test_msg.tdop = 155; - test_msg.tow = 407155000; - test_msg.vdop = 112; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gdop, 348) - << "incorrect value for last_msg_.gdop, expected 348, is " - << last_msg_.gdop; - EXPECT_EQ(last_msg_.hdop, 637) - << "incorrect value for last_msg_.hdop, expected 637, is " - << last_msg_.hdop; - EXPECT_EQ(last_msg_.pdop, 311) - << "incorrect value for last_msg_.pdop, expected 311, is " - << last_msg_.pdop; - EXPECT_EQ(last_msg_.tdop, 155) - << "incorrect value for last_msg_.tdop, expected 155, is " - << last_msg_.tdop; - EXPECT_EQ(last_msg_.tow, 407155000) - << "incorrect value for last_msg_.tow, expected 407155000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vdop, 112) - << "incorrect value for last_msg_.vdop, expected 112, is " - << last_msg_.vdop; + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA2() { + assign(test_msg_.gdop, 180); + assign(test_msg_.hdop, 160); + assign(test_msg_.pdop, 190); + assign(test_msg_.tdop, 170); + assign(test_msg_.tow, 2570200); + assign(test_msg_.vdop, 150); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xda47; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 246, 215, 14, 216, 55, 39, 0, 180, + 0, 190, 0, 170, 0, 160, 0, 150, 0, 71, 218, + }; + uint8_t encoded_payload_[14] = { + 216, 55, 39, 0, 180, 0, 190, 0, 170, 0, 160, 0, 150, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA3() { + assign(test_msg_.gdop, 247); + assign(test_msg_.hdop, 273); + assign(test_msg_.pdop, 215); + assign(test_msg_.tdop, 123); + assign(test_msg_.tow, 407084500); + assign(test_msg_.vdop, 44); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x15ce; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 212, 157, 67, 24, 247, + 0, 215, 0, 123, 0, 17, 1, 44, 0, 206, 21, + }; + uint8_t encoded_payload_[14] = { + 212, 157, 67, 24, 247, 0, 215, 0, 123, 0, 17, 1, 44, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA4() { + assign(test_msg_.gdop, 65535); + assign(test_msg_.hdop, 0); + assign(test_msg_.pdop, 65535); + assign(test_msg_.tdop, 0); + assign(test_msg_.tow, 0); + assign(test_msg_.vdop, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xc92; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 0, 0, 0, 0, 255, + 255, 255, 255, 0, 0, 0, 0, 0, 0, 146, 12, + }; + uint8_t encoded_payload_[14] = { + 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA5() { + assign(test_msg_.gdop, 348); + assign(test_msg_.hdop, 637); + assign(test_msg_.pdop, 312); + assign(test_msg_.tdop, 155); + assign(test_msg_.tow, 407152000); + assign(test_msg_.vdop, 113); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x5d81; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 128, 165, 68, 24, 92, + 1, 56, 1, 155, 0, 125, 2, 113, 0, 129, 93, + }; + uint8_t encoded_payload_[14] = { + 128, 165, 68, 24, 92, 1, 56, 1, 155, 0, 125, 2, 113, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA6() { + assign(test_msg_.gdop, 348); + assign(test_msg_.hdop, 637); + assign(test_msg_.pdop, 311); + assign(test_msg_.tdop, 155); + assign(test_msg_.tow, 407153000); + assign(test_msg_.vdop, 113); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x80d1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 104, 169, 68, 24, 92, + 1, 55, 1, 155, 0, 125, 2, 113, 0, 209, 128, + }; + uint8_t encoded_payload_[14] = { + 104, 169, 68, 24, 92, 1, 55, 1, 155, 0, 125, 2, 113, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA7() { + assign(test_msg_.gdop, 348); + assign(test_msg_.hdop, 637); + assign(test_msg_.pdop, 311); + assign(test_msg_.tdop, 155); + assign(test_msg_.tow, 407154000); + assign(test_msg_.vdop, 112); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x61e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 80, 173, 68, 24, 92, + 1, 55, 1, 155, 0, 125, 2, 112, 0, 30, 6, + }; + uint8_t encoded_payload_[14] = { + 80, 173, 68, 24, 92, 1, 55, 1, 155, 0, 125, 2, 112, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgDopsDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgDopsDepA8() { + assign(test_msg_.gdop, 348); + assign(test_msg_.hdop, 637); + assign(test_msg_.pdop, 311); + assign(test_msg_.tdop, 155); + assign(test_msg_.tow, 407155000); + assign(test_msg_.vdop, 112); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dops_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDopsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dops_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDopsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dops_dep_a, sizeof(msg->dops_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dops_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dops_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDopsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x4346; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_dops_dep_a_t &lesser, + const sbp_msg_dops_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dops_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dops_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dops_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDopsDepA, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dops_dep_a_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { + 85, 6, 2, 195, 4, 14, 56, 177, 68, 24, 92, + 1, 55, 1, 155, 0, 125, 2, 112, 0, 70, 67, + }; + uint8_t encoded_payload_[14] = { + 56, 177, 68, 24, 92, 1, 55, 1, 155, 0, 125, 2, 112, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dops_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDopsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgDopsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ( + sbp_msg_dops_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ(sbp_msg_dops_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDopsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_dops_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dops_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDopsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.gdop, greater.gdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hdop, greater.hdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.pdop, greater.pdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tdop, greater.tdop); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_dops_dep_a_t lesser = info.test_msg; + sbp_msg_dops_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vdop, greater.vdop); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgDopsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DOPS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dops_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dops_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dops_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dops_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dops_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDopsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgDopsDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgDopsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTime.cc b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTime.cc index 40f929f23d..dea96cb05e 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTime.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTime.cc @@ -16,461 +16,2844 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgGPSTime0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgGPSTime0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTime0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTime0() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 166900); + assign(test_msg_.tow, 326825000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time, sizeof(msg->gps_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTime); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x9822; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_t &lesser, + const sbp_msg_gps_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTime0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 2, 1, 211, 136, 11, 128, 7, 40, 244, 122, 19, 244, 139, 2, 0, 0, 34, 152, }; + uint8_t encoded_payload_[11] = { + 128, 7, 40, 244, 122, 19, 244, 139, 2, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgGpsTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_gps_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGpsTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_GPS_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); - sbp_msg_gps_time_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 166900; - test_msg.tow = 326825000; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 166900) - << "incorrect value for last_msg_.ns_residual, expected 166900, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTime1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgGpsTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTime1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTime1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTime1() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 256638); + assign(test_msg_.tow, 326825500); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time, sizeof(msg->gps_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTime); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x341; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_t &lesser, + const sbp_msg_gps_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTime1, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 2, 1, 211, 136, 11, 128, 7, 28, 246, 122, 19, 126, 234, 3, 0, 0, 65, 3, }; + uint8_t encoded_payload_[11] = { + 128, 7, 28, 246, 122, 19, 126, 234, 3, 0, 0, + }; +}; - sbp_msg_gps_time_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 256638; - test_msg.tow = 326825500; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 256638) - << "incorrect value for last_msg_.ns_residual, expected 256638, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326825500) - << "incorrect value for last_msg_.tow, expected 326825500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTime2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTime2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgGpsTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTime2, Test) { - uint8_t encoded_frame[] = { - 85, 2, 1, 211, 136, 11, 128, 7, 16, 248, - 122, 19, 129, 12, 4, 0, 0, 12, 84, - }; + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_gps_time_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 265345; - test_msg.tow = 326826000; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 265345) - << "incorrect value for last_msg_.ns_residual, expected 265345, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTime3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTime3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_gps_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTime3, Test) { - uint8_t encoded_frame[] = { - 85, 2, 1, 211, 136, 11, 128, 7, 4, 250, - 122, 19, 137, 204, 4, 0, 0, 50, 165, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_gps_time_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 314505; - test_msg.tow = 326826500; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 314505) - << "incorrect value for last_msg_.ns_residual, expected 314505, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326826500) - << "incorrect value for last_msg_.tow, expected 326826500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTime4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTime4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTime4, Test) { - uint8_t encoded_frame[] = { - 85, 2, 1, 211, 136, 11, 128, 7, 248, 251, - 122, 19, 181, 137, 5, 0, 0, 180, 33, - }; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_gps_time_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 362933; - test_msg.tow = 326827000; - test_msg.wn = 1920; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGpsTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_GPS_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time, info.test_msg); +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 362933) - << "incorrect value for last_msg_.ns_residual, expected 362933, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); } + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgGpsTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTime2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTime2() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 265345); + assign(test_msg_.tow, 326826000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time, sizeof(msg->gps_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTime); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x540c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_t &lesser, + const sbp_msg_gps_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 2, 1, 211, 136, 11, 128, 7, 16, 248, + 122, 19, 129, 12, 4, 0, 0, 12, 84, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 16, 248, 122, 19, 129, 12, 4, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgGpsTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_gps_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGpsTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_GPS_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgGpsTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTime3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTime3() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 314505); + assign(test_msg_.tow, 326826500); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time, sizeof(msg->gps_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTime); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xa532; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_t &lesser, + const sbp_msg_gps_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 2, 1, 211, 136, 11, 128, 7, 4, 250, + 122, 19, 137, 204, 4, 0, 0, 50, 165, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 4, 250, 122, 19, 137, 204, 4, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgGpsTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_gps_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGpsTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_GPS_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgGpsTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTime4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTime4() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 362933); + assign(test_msg_.tow, 326827000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time, sizeof(msg->gps_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTime); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x21b4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_t &lesser, + const sbp_msg_gps_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgGpsTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgGpsTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 2, 1, 211, 136, 11, 128, 7, 248, 251, + 122, 19, 181, 137, 5, 0, 0, 180, 33, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 248, 251, 122, 19, 181, 137, 5, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgGpsTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ( + sbp_msg_gps_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_gps_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_t lesser = info.test_msg; + sbp_msg_gps_time_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGpsTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_GPS_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTime4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgGpsTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeDepA.cc index 4b5e38f733..2ca0611638 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeDepA.cc @@ -16,1000 +16,6420 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgGPSTimeDepA0 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA0() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 0); + assign(test_msg_.tow, 2567800); + assign(test_msg_.wn, 1787); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x2485; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 246, 215, 11, 251, 6, 120, 46, 39, 0, 0, 0, 0, 0, 0, 133, 36, + }; + uint8_t encoded_payload_[11] = { + 251, 6, 120, 46, 39, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA1 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA1() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 0); + assign(test_msg_.tow, 2567900); + assign(test_msg_.wn, 1787); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xa024; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 246, 215, 11, 251, 6, 220, 46, 39, 0, 0, 0, 0, 0, 0, 36, 160, + }; + uint8_t encoded_payload_[11] = { + 251, 6, 220, 46, 39, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA2() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 0); + assign(test_msg_.tow, 2568000); + assign(test_msg_.wn, 1787); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xbeab; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 246, 215, 11, 251, 6, 64, 47, 39, 0, 0, 0, 0, 0, 0, 171, 190, + }; + uint8_t encoded_payload_[11] = { + 251, 6, 64, 47, 39, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA3() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 0); + assign(test_msg_.tow, 2568100); + assign(test_msg_.wn, 1787); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x65d3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 246, 215, 11, 251, 6, 164, 47, 39, 0, 0, 0, 0, 0, 0, 211, 101, + }; + uint8_t encoded_payload_[11] = { + 251, 6, 164, 47, 39, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA4() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 0); + assign(test_msg_.tow, 2568200); + assign(test_msg_.wn, 1787); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x2cfb; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 246, 215, 11, 251, 6, 8, 48, 39, 0, 0, 0, 0, 0, 0, 251, 44, + }; + uint8_t encoded_payload_[11] = { + 251, 6, 8, 48, 39, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA5() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, -224401); + assign(test_msg_.tow, 407084500); + assign(test_msg_.wn, 1838); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xbed7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 195, 4, 11, 46, 7, 212, 157, + 67, 24, 111, 147, 252, 255, 0, 215, 190, + }; + uint8_t encoded_payload_[11] = { + 46, 7, 212, 157, 67, 24, 111, 147, 252, 255, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA6() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 223085); + assign(test_msg_.tow, 407084600); + assign(test_msg_.wn, 1838); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x5986; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 195, 4, 11, 46, 7, 56, 158, 67, 24, 109, 103, 3, 0, 0, 134, 89, + }; + uint8_t encoded_payload_[11] = { + 46, 7, 56, 158, 67, 24, 109, 103, 3, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA7() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, -222999); + assign(test_msg_.tow, 407084700); + assign(test_msg_.wn, 1838); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xf1ce; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 195, 4, 11, 46, 7, 156, 158, + 67, 24, 233, 152, 252, 255, 0, 206, 241, + }; + uint8_t encoded_payload_[11] = { + 46, 7, 156, 158, 67, 24, 233, 152, 252, 255, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeDepA8() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 236272); + assign(test_msg_.tow, 407084800); + assign(test_msg_.wn, 1838); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6293; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 195, 4, 11, 46, 7, 0, 159, 67, 24, 240, 154, 3, 0, 0, 147, 98, + }; + uint8_t encoded_payload_[11] = { + 46, 7, 0, 159, 67, 24, 240, 154, 3, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA9 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTimeDepA9() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, -236144); + assign(test_msg_.tow, 407084900); + assign(test_msg_.wn, 1838); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA0, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 246, 215, 11, 251, 6, 120, 46, 39, 0, 0, 0, 0, 0, 0, 133, 36, + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } }; - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 0; - test_msg.tow = 2567800; - test_msg.wn = 1787; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 0) - << "incorrect value for last_msg_.ns_residual, expected 0, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1787) - << "incorrect value for last_msg_.wn, expected 1787, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x98ba; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 246, 215, 11, 251, 6, 220, 46, 39, 0, 0, 0, 0, 0, 0, 36, 160, - }; + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 0; - test_msg.tow = 2567900; - test_msg.wn = 1787; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 0) - << "incorrect value for last_msg_.ns_residual, expected 0, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1787) - << "incorrect value for last_msg_.wn, expected 1787, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 246, 215, 11, 251, 6, 64, 47, 39, 0, 0, 0, 0, 0, 0, 171, 190, - }; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 0; - test_msg.tow = 2568000; - test_msg.wn = 1787; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 0) - << "incorrect value for last_msg_.ns_residual, expected 0, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 2568000) - << "incorrect value for last_msg_.tow, expected 2568000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1787) - << "incorrect value for last_msg_.wn, expected 1787, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 246, 215, 11, 251, 6, 164, 47, 39, 0, 0, 0, 0, 0, 0, 211, 101, + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 0, 1, 195, 4, 11, 46, 7, 100, 159, + 67, 24, 144, 101, 252, 255, 0, 186, 152, }; + uint8_t encoded_payload_[11] = { + 46, 7, 100, 159, 67, 24, 144, 101, 252, 255, 0, + }; +}; - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 0; - test_msg.tow = 2568100; - test_msg.wn = 1787; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 0) - << "incorrect value for last_msg_.ns_residual, expected 0, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 2568100) - << "incorrect value for last_msg_.tow, expected 2568100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1787) - << "incorrect value for last_msg_.wn, expected 1787, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 246, 215, 11, 251, 6, 8, 48, 39, 0, 0, 0, 0, 0, 0, 251, 44, - }; + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 0; - test_msg.tow = 2568200; - test_msg.wn = 1787; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 0) - << "incorrect value for last_msg_.ns_residual, expected 0, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 2568200) - << "incorrect value for last_msg_.tow, expected 2568200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1787) - << "incorrect value for last_msg_.wn, expected 1787, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 195, 4, 11, 46, 7, 212, 157, - 67, 24, 111, 147, 252, 255, 0, 215, 190, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = -224401; - test_msg.tow = 407084500; - test_msg.wn = 1838; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, -224401) - << "incorrect value for last_msg_.ns_residual, expected -224401, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 195, 4, 11, 46, 7, 56, 158, 67, 24, 109, 103, 3, 0, 0, 134, 89, - }; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 223085; - test_msg.tow = 407084600; - test_msg.wn = 1838; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 223085) - << "incorrect value for last_msg_.ns_residual, expected 223085, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407084600) - << "incorrect value for last_msg_.tow, expected 407084600, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 195, 4, 11, 46, 7, 156, 158, - 67, 24, 233, 152, 252, 255, 0, 206, 241, - }; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = -222999; - test_msg.tow = 407084700; - test_msg.wn = 1838; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, -222999) - << "incorrect value for last_msg_.ns_residual, expected -222999, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407084700) - << "incorrect value for last_msg_.tow, expected 407084700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 195, 4, 11, 46, 7, 0, 159, 67, 24, 240, 154, 3, 0, 0, 147, 98, - }; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 236272; - test_msg.tow = 407084800; - test_msg.wn = 1838; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 236272) - << "incorrect value for last_msg_.ns_residual, expected 236272, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407084800) - << "incorrect value for last_msg_.tow, expected 407084800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeDepA10 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTimeDepA10() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, -334131); + assign(test_msg_.tow, 407151150); + assign(test_msg_.wn, 1838); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 0, 1, 195, 4, 11, 46, 7, 100, 159, - 67, 24, 144, 101, 252, 255, 0, 186, 152, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = -236144; - test_msg.tow = 407084900; - test_msg.wn = 1838; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, -236144) - << "incorrect value for last_msg_.ns_residual, expected -236144, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407084900) - << "incorrect value for last_msg_.tow, expected 407084900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_dep_a, + sizeof(msg->gps_time_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xe10b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_dep_a_t &lesser, + const sbp_msg_gps_time_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeDepA, &wrapped_greater, &wrapped_lesser), + 0); -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeDepA10, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_dep_a_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 0, 1, 195, 4, 11, 46, 7, 46, 162, 68, 24, 205, 230, 250, 255, 0, 11, 225, }; + uint8_t encoded_payload_[11] = { + 46, 7, 46, 162, 68, 24, 205, 230, 250, 255, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ( + sbp_msg_gps_time_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_gps_time_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = -334131; - test_msg.tow = 407151150; - test_msg.wn = 1838; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_dep_a_t lesser = info.test_msg; + sbp_msg_gps_time_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.gps_time_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + sbp::State state{}; + state.set_reader(&reader); - while (dummy_rd_ < dummy_wr_) { - process(); + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, -334131) - << "incorrect value for last_msg_.ns_residual, expected -334131, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 407151150) - << "incorrect value for last_msg_.tow, expected 407151150, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1838) - << "incorrect value for last_msg_.wn, expected 1838, is " << last_msg_.wn; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeGNSS.cc b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeGNSS.cc index 3173164525..f8ec757d45 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeGNSS.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgGPSTimeGNSS.cc @@ -16,461 +16,2914 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgGPSTimeGNSS0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgGPSTimeGNSS0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTimeGNSS0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTimeGNSS0() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 166900); + assign(test_msg_.tow, 326825000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_gnss, + sizeof(msg->gps_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeGnss); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x5899; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_gnss_t &lesser, + const sbp_msg_gps_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeGNSS0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 4, 1, 211, 136, 11, 128, 7, 40, 244, 122, 19, 244, 139, 2, 0, 0, 153, 88, }; + uint8_t encoded_payload_[11] = { + 128, 7, 40, 244, 122, 19, 244, 139, 2, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); - sbp_msg_gps_time_gnss_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 166900; - test_msg.tow = 326825000; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 166900) - << "incorrect value for last_msg_.ns_residual, expected 166900, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeGNSS1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeGNSS1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgGPSTimeGNSS1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgGPSTimeGNSS1() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 256638); + assign(test_msg_.tow, 326825500); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_gnss, + sizeof(msg->gps_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeGnss); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xc3fa; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_gps_time_gnss_t &lesser, + const sbp_msg_gps_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeGNSS1, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 4, 1, 211, 136, 11, 128, 7, 28, 246, 122, 19, 126, 234, 3, 0, 0, 250, 195, }; + uint8_t encoded_payload_[11] = { + 128, 7, 28, 246, 122, 19, 126, 234, 3, 0, 0, + }; +}; - sbp_msg_gps_time_gnss_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 256638; - test_msg.tow = 326825500; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 256638) - << "incorrect value for last_msg_.ns_residual, expected 256638, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326825500) - << "incorrect value for last_msg_.tow, expected 326825500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeGNSS2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeGNSS2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeGNSS2, Test) { - uint8_t encoded_frame[] = { - 85, 4, 1, 211, 136, 11, 128, 7, 16, 248, - 122, 19, 129, 12, 4, 0, 0, 183, 148, - }; + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_gps_time_gnss_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 265345; - test_msg.tow = 326826000; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 265345) - << "incorrect value for last_msg_.ns_residual, expected 265345, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeGNSS3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeGNSS3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeGNSS3, Test) { - uint8_t encoded_frame[] = { - 85, 4, 1, 211, 136, 11, 128, 7, 4, 250, - 122, 19, 137, 204, 4, 0, 0, 137, 101, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_gps_time_gnss_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 314505; - test_msg.tow = 326826500; - test_msg.wn = 1920; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 314505) - << "incorrect value for last_msg_.ns_residual, expected 314505, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326826500) - << "incorrect value for last_msg_.tow, expected 326826500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; -} -class Test_auto_check_sbp_navigation_MsgGPSTimeGNSS4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgGPSTimeGNSS4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_gps_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_gps_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgGPSTimeGNSS4, Test) { - uint8_t encoded_frame[] = { - 85, 4, 1, 211, 136, 11, 128, 7, 248, 251, - 122, 19, 181, 137, 5, 0, 0, 15, 225, - }; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_gps_time_gnss_t test_msg{}; - test_msg.flags = 0; - test_msg.ns_residual = 362933; - test_msg.tow = 326827000; - test_msg.wn = 1920; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time_gnss, info.test_msg); +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.ns_residual, 362933) - << "incorrect value for last_msg_.ns_residual, expected 362933, is " - << last_msg_.ns_residual; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 1920) - << "incorrect value for last_msg_.wn, expected 1920, is " << last_msg_.wn; +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); } + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeGNSS2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeGNSS2() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 265345); + assign(test_msg_.tow, 326826000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_gnss, + sizeof(msg->gps_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeGnss); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x94b7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_gnss_t &lesser, + const sbp_msg_gps_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 4, 1, 211, 136, 11, 128, 7, 16, 248, + 122, 19, 129, 12, 4, 0, 0, 183, 148, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 16, 248, 122, 19, 129, 12, 4, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeGNSS3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeGNSS3() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 314505); + assign(test_msg_.tow, 326826500); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_gnss, + sizeof(msg->gps_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeGnss); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x6589; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_gnss_t &lesser, + const sbp_msg_gps_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 4, 1, 211, 136, 11, 128, 7, 4, 250, + 122, 19, 137, 204, 4, 0, 0, 137, 101, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 4, 250, 122, 19, 137, 204, 4, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgGPSTimeGNSS4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgGPSTimeGNSS4() { + assign(test_msg_.flags, 0); + assign(test_msg_.ns_residual, 362933); + assign(test_msg_.tow, 326827000); + assign(test_msg_.wn, 1920); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_gps_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGpsTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_gps_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGpsTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->gps_time_gnss, + sizeof(msg->gps_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_gps_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.gps_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGpsTimeGnss); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xe10f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_gps_time_gnss_t &lesser, + const sbp_msg_gps_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_gps_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_gps_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_gps_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGpsTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_gps_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { + 85, 4, 1, 211, 136, 11, 128, 7, 248, 251, + 122, 19, 181, 137, 5, 0, 0, 15, 225, + }; + uint8_t encoded_payload_[11] = { + 128, 7, 248, 251, 122, 19, 181, 137, 5, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_gps_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGpsTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_gps_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGpsTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_gps_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_gps_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGpsTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns_residual, greater.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_gps_time_gnss_t lesser = info.test_msg; + sbp_msg_gps_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgGpsTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GPS_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_gps_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_gps_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.gps_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.gps_time_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_gps_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGpsTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgGPSTimeGNSS4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGpsTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEF.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEF.cc index 6fa02cf9d5..0ecf50a46e 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEF.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEF.cc @@ -16,426 +16,2374 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosECEF0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosECEF0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEF0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEF0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.x, -2684269.0326572997); + assign(test_msg_.y, -4316646.751816); + assign(test_msg_.z, 3839646.7095350414); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef, sizeof(msg->pos_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x654; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_t &lesser, + const sbp_msg_pos_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEF0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { 85, 9, 2, 211, 136, 32, 16, 248, 122, 19, 73, 29, 46, 132, 182, 122, 68, 193, 219, 192, 29, 176, 121, 119, 80, 193, 83, 11, 210, 90, 79, 75, 77, 65, 0, 0, 15, 2, 84, 6, }; + uint8_t encoded_payload_[32] = { + 16, 248, 122, 19, 73, 29, 46, 132, 182, 122, 68, + 193, 219, 192, 29, 176, 121, 119, 80, 193, 83, 11, + 210, 90, 79, 75, 77, 65, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - sbp_msg_pos_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 2; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.x = -2684269.0326572997; - test_msg.y = -4316646.751816; - test_msg.z = 3839646.7095350414; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2684269.03266 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2684269.03266, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4316646.75182 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4316646.75182, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3839646.70954 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3839646.70954, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEF1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEF1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEF1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEF1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.x, -2684269.064252186); + assign(test_msg_.y, -4316646.762264892); + assign(test_msg_.z, 3839646.463913912); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef, sizeof(msg->pos_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xd893; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_t &lesser, + const sbp_msg_pos_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEF1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_pos_ecef_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { 85, 9, 2, 211, 136, 32, 248, 251, 122, 19, 103, 106, 57, 136, 182, 122, 68, 193, 176, 242, 200, 176, 121, 119, 80, 193, 244, 135, 97, 59, 79, 75, 77, 65, 0, 0, 15, 2, 147, 216, }; + uint8_t encoded_payload_[32] = { + 248, 251, 122, 19, 103, 106, 57, 136, 182, 122, 68, + 193, 176, 242, 200, 176, 121, 119, 80, 193, 244, 135, + 97, 59, 79, 75, 77, 65, 0, 0, 15, 2, + }; +}; - sbp_msg_pos_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 2; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.x = -2684269.064252186; - test_msg.y = -4316646.762264892; - test_msg.z = 3839646.463913912; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2684269.06425 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2684269.06425, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4316646.76226 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4316646.76226, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3839646.46391 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3839646.46391, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEF2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEF2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEF2, Test) { - uint8_t encoded_frame[] = { - 85, 9, 2, 211, 136, 32, 224, 255, 122, 19, 101, 179, 242, 182, - 182, 122, 68, 193, 130, 196, 145, 199, 121, 119, 80, 193, 212, 10, - 253, 15, 79, 75, 77, 65, 0, 0, 15, 2, 40, 201, - }; + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_pos_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 2; - test_msg.n_sats = 15; - test_msg.tow = 326828000; - test_msg.x = -2684269.4292816394; - test_msg.y = -4316647.118271949; - test_msg.z = 3839646.124909738; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326828000) - << "incorrect value for last_msg_.tow, expected 326828000, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2684269.42928 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2684269.42928, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4316647.11827 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4316647.11827, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3839646.12491 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3839646.12491, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEF3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEF3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEF3, Test) { - uint8_t encoded_frame[] = { - 85, 9, 2, 211, 136, 32, 200, 3, 123, 19, 146, 214, 132, 215, - 182, 122, 68, 193, 213, 68, 49, 215, 121, 119, 80, 193, 71, 34, - 110, 243, 78, 75, 77, 65, 0, 0, 15, 2, 187, 86, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_pos_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 2; - test_msg.n_sats = 15; - test_msg.tow = 326829000; - test_msg.x = -2684269.683741399; - test_msg.y = -4316647.3623821335; - test_msg.z = 3839645.90179852; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326829000) - << "incorrect value for last_msg_.tow, expected 326829000, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2684269.68374 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2684269.68374, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4316647.36238 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4316647.36238, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3839645.9018 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3839645.9018, is " - << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_ECEF"); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEF2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEF2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326828000); + assign(test_msg_.x, -2684269.4292816394); + assign(test_msg_.y, -4316647.118271949); + assign(test_msg_.z, 3839646.124909738); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef, sizeof(msg->pos_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xc928; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_t &lesser, + const sbp_msg_pos_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 9, 2, 211, 136, 32, 224, 255, 122, 19, 101, 179, 242, 182, + 182, 122, 68, 193, 130, 196, 145, 199, 121, 119, 80, 193, 212, 10, + 253, 15, 79, 75, 77, 65, 0, 0, 15, 2, 40, 201, + }; + uint8_t encoded_payload_[32] = { + 224, 255, 122, 19, 101, 179, 242, 182, 182, 122, 68, + 193, 130, 196, 145, 199, 121, 119, 80, 193, 212, 10, + 253, 15, 79, 75, 77, 65, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEF3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEF3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326829000); + assign(test_msg_.x, -2684269.683741399); + assign(test_msg_.y, -4316647.3623821335); + assign(test_msg_.z, 3839645.90179852); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef, sizeof(msg->pos_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x56bb; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_t &lesser, + const sbp_msg_pos_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 9, 2, 211, 136, 32, 200, 3, 123, 19, 146, 214, 132, 215, + 182, 122, 68, 193, 213, 68, 49, 215, 121, 119, 80, 193, 71, 34, + 110, 243, 78, 75, 77, 65, 0, 0, 15, 2, 187, 86, + }; + uint8_t encoded_payload_[32] = { + 200, 3, 123, 19, 146, 214, 132, 215, 182, 122, 68, + 193, 213, 68, 49, 215, 121, 119, 80, 193, 71, 34, + 110, 243, 78, 75, 77, 65, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ( + sbp_msg_pos_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_t lesser = info.test_msg; + sbp_msg_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEF3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCov.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCov.cc index 684dd28174..b2db59ffc8 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCov.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCov.cc @@ -16,128 +16,651 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosECEFCov0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosECEFCov0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEFCov0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEFCov0() { + assign(test_msg_.cov_x_x, 8.0); + assign(test_msg_.cov_x_y, 7.0); + assign(test_msg_.cov_x_z, 2.0); + assign(test_msg_.cov_y_y, 6.0); + assign(test_msg_.cov_y_z, 8.0); + assign(test_msg_.cov_z_z, 5.0); + assign(test_msg_.flags, 5); + assign(test_msg_.n_sats, 4); + assign(test_msg_.tow, 7); + assign(test_msg_.x, 6.0); + assign(test_msg_.y, 1.0); + assign(test_msg_.z, 4.0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_cov_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_cov_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefCov, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_cov_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefCov); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_cov, + sizeof(msg->pos_ecef_cov)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_cov_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_cov, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefCov); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xa7f9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 54; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_cov_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_cov_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_cov_t &lesser, + const sbp_msg_pos_ecef_cov_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cov_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cov_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cov_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cov_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefCov, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefCov, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefCov, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefCov, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFCov0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_cov_t test_msg_{}; + uint8_t encoded_frame_[54 + 8] = { 85, 20, 2, 66, 0, 54, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 64, 0, 0, 0, 0, 0, 0, 240, 63, 0, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 65, 0, 0, 224, 64, 0, 0, 0, 64, 0, 0, 192, 64, 0, 0, 0, 65, 0, 0, 160, 64, 4, 5, 249, 167, }; + uint8_t encoded_payload_[54] = { + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 64, 0, 0, 0, 0, 0, 0, + 240, 63, 0, 0, 0, 0, 0, 0, 16, 64, 0, 0, 0, 65, 0, 0, 224, 64, + 0, 0, 0, 64, 0, 0, 192, 64, 0, 0, 0, 65, 0, 0, 160, 64, 4, 5, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_cov_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefCov, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefCov, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + for (uint8_t i = 0; i < 54; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_cov_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefCov, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_ecef_cov_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_cov_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefCov, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_ecef_cov_t test_msg{}; - test_msg.cov_x_x = 8.0; - test_msg.cov_x_y = 7.0; - test_msg.cov_x_z = 2.0; - test_msg.cov_y_y = 6.0; - test_msg.cov_y_z = 8.0; - test_msg.cov_z_z = 5.0; - test_msg.flags = 5; - test_msg.n_sats = 4; - test_msg.tow = 7; - test_msg.x = 6.0; - test_msg.y = 1.0; - test_msg.z = 4.0; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_x_x * 100 - 8.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_x, expected 8.0, is " - << last_msg_.cov_x_x; - EXPECT_LT((last_msg_.cov_x_y * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_y, expected 7.0, is " - << last_msg_.cov_x_y; - EXPECT_LT((last_msg_.cov_x_z * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_z, expected 2.0, is " - << last_msg_.cov_x_z; - EXPECT_LT((last_msg_.cov_y_y * 100 - 6.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_y, expected 6.0, is " - << last_msg_.cov_y_y; - EXPECT_LT((last_msg_.cov_y_z * 100 - 8.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_z, expected 8.0, is " - << last_msg_.cov_y_z; - EXPECT_LT((last_msg_.cov_z_z * 100 - 5.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_z_z, expected 5.0, is " - << last_msg_.cov_z_z; - EXPECT_EQ(last_msg_.flags, 5) - << "incorrect value for last_msg_.flags, expected 5, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 4) - << "incorrect value for last_msg_.n_sats, expected 4, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 7) - << "incorrect value for last_msg_.tow, expected 7, is " << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - 6.0 * 100), 0.05) - << "incorrect value for last_msg_.x, expected 6.0, is " << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.y, expected 1.0, is " << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 4.0 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 4.0, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_x, greater.cov_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_y, greater.cov_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_z, greater.cov_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_y, greater.cov_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_z, greater.cov_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_z_z, greater.cov_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefCov); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_COV"); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_cov_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_cov_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_cov, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef_cov, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefCov, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCov0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefCov, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCovGNSS.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCovGNSS.cc index 84626db9c0..82d8fce10f 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCovGNSS.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFCovGNSS.cc @@ -16,135 +16,665 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosECEFCovGNSS0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEFCovGNSS0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0() { + assign(test_msg_.cov_x_x, 0.009699014946818352); + assign(test_msg_.cov_x_y, 0.009086096659302711); + assign(test_msg_.cov_x_z, -0.006058753002434969); + assign(test_msg_.cov_y_y, 0.020321274176239967); + assign(test_msg_.cov_y_z, -0.009988312609493732); + assign(test_msg_.cov_z_z, 0.01487385667860508); + assign(test_msg_.flags, 4); + assign(test_msg_.n_sats, 18); + assign(test_msg_.tow, 501867800); + assign(test_msg_.x, -2694229.7079770807); + assign(test_msg_.y, -4264073.427345817); + assign(test_msg_.z, 3890655.013186158); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_cov_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_cov_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefCovGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_cov_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefCovGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_cov_gnss, + sizeof(msg->pos_ecef_cov_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_cov_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_cov_gnss, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefCovGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0x669f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 54; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_cov_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_cov_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_cov_gnss_t &lesser, + const sbp_msg_pos_ecef_cov_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_cov_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_cov_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefCovGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosEcefCovGnss, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosEcefCovGnss, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosEcefCovGnss, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFCovGNSS0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_cov_gnss_t test_msg_{}; + uint8_t encoded_frame_[54 + 8] = { 85, 52, 2, 0, 16, 54, 24, 229, 233, 29, 52, 254, 158, 218, 42, 142, 68, 193, 69, 162, 89, 91, 34, 68, 80, 193, 131, 21, 176, 129, 239, 174, 77, 65, 158, 232, 30, 60, 218, 221, 20, 60, 129, 136, 198, 187, 205, 120, 166, 60, 5, 166, 35, 188, 122, 177, 115, 60, 18, 4, 159, 102, }; + uint8_t encoded_payload_[54] = { + 24, 229, 233, 29, 52, 254, 158, 218, 42, 142, 68, 193, 69, 162, + 89, 91, 34, 68, 80, 193, 131, 21, 176, 129, 239, 174, 77, 65, + 158, 232, 30, 60, 218, 221, 20, 60, 129, 136, 198, 187, 205, 120, + 166, 60, 5, 166, 35, 188, 122, 177, 115, 60, 18, 4, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgPosEcefCovGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefCovGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + for (uint8_t i = 0; i < 54; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_cov_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefCovGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_cov_gnss_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefCovGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_ecef_cov_gnss_t test_msg{}; - test_msg.cov_x_x = 0.009699014946818352; - test_msg.cov_x_y = 0.009086096659302711; - test_msg.cov_x_z = -0.006058753002434969; - test_msg.cov_y_y = 0.020321274176239967; - test_msg.cov_y_z = -0.009988312609493732; - test_msg.cov_z_z = 0.01487385667860508; - test_msg.flags = 4; - test_msg.n_sats = 18; - test_msg.tow = 501867800; - test_msg.x = -2694229.7079770807; - test_msg.y = -4264073.427345817; - test_msg.z = 3890655.013186158; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_x_x * 100 - 0.00969901494682 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_x, expected 0.00969901494682, is " - << last_msg_.cov_x_x; - EXPECT_LT((last_msg_.cov_x_y * 100 - 0.0090860966593 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_y, expected 0.0090860966593, is " - << last_msg_.cov_x_y; - EXPECT_LT((last_msg_.cov_x_z * 100 - -0.00605875300243 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_z, expected -0.00605875300243, " - "is " - << last_msg_.cov_x_z; - EXPECT_LT((last_msg_.cov_y_y * 100 - 0.0203212741762 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_y, expected 0.0203212741762, is " - << last_msg_.cov_y_y; - EXPECT_LT((last_msg_.cov_y_z * 100 - -0.00998831260949 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_z, expected -0.00998831260949, " - "is " - << last_msg_.cov_y_z; - EXPECT_LT((last_msg_.cov_z_z * 100 - 0.0148738566786 * 100), 0.05) - << "incorrect value for last_msg_.cov_z_z, expected 0.0148738566786, is " - << last_msg_.cov_z_z; - EXPECT_EQ(last_msg_.flags, 4) - << "incorrect value for last_msg_.flags, expected 4, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 18) - << "incorrect value for last_msg_.n_sats, expected 18, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2694229.70798 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2694229.70798, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4264073.42735 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4264073.42735, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3890655.01319 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3890655.01319, is " - << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_x, greater.cov_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_y, greater.cov_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_z, greater.cov_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_y, greater.cov_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_z, greater.cov_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_z_z, greater.cov_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefCovGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_COV_GNSS"); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_cov_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_cov_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.pos_ecef_cov_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_cov_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefCovGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFCovGNSS0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefCovGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFDepA.cc index 3ef6652a78..bb9e6a1066 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFDepA.cc @@ -16,1161 +16,6685 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosECEFDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosECEFDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEFDepA0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.x, -2700354.5912927105); + assign(test_msg_.y, -4292510.764041577); + assign(test_msg_.z, 3855357.977260149); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x560d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { 85, 0, 2, 246, 215, 32, 20, 46, 39, 0, 195, 122, 175, 75, 33, 154, 68, 193, 164, 14, 230, 176, 231, 95, 80, 193, 78, 220, 22, 253, 254, 105, 77, 65, 0, 0, 9, 0, 13, 86, }; + uint8_t encoded_payload_[32] = { + 20, 46, 39, 0, 195, 122, 175, 75, 33, 154, 68, + 193, 164, 14, 230, 176, 231, 95, 80, 193, 78, 220, + 22, 253, 254, 105, 77, 65, 0, 0, 9, 0, + }; +}; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.x = -2700354.5912927105; - test_msg.y = -4292510.764041577; - test_msg.z = 3855357.977260149; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2700354.59129 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2700354.59129, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4292510.76404 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4292510.76404, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3855357.97726 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3855357.97726, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 246, 215, 32, 20, 46, 39, 0, 212, 196, 12, 42, - 34, 154, 68, 193, 9, 113, 112, 123, 231, 95, 80, 193, 54, 97, - 38, 192, 254, 105, 77, 65, 0, 0, 9, 1, 75, 143, - }; + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.x = -2700356.3285146747; - test_msg.y = -4292509.928737887; - test_msg.z = 3855357.5011712564; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2700356.32851 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2700356.32851, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4292509.92874 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4292509.92874, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3855357.50117 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3855357.50117, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 246, 215, 32, 120, 46, 39, 0, 112, 97, 39, 190, - 34, 154, 68, 193, 230, 43, 119, 115, 231, 95, 80, 193, 50, 199, - 76, 66, 254, 105, 77, 65, 0, 0, 9, 0, 204, 113, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.x = -2700357.485576801; - test_msg.y = -4292509.80414865; - test_msg.z = 3855356.517968082; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2700357.48558 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2700357.48558, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4292509.80415 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4292509.80415, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3855356.51797 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3855356.51797, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 246, 215, 32, 120, 46, 39, 0, 194, 82, 121, 4, - 34, 154, 68, 193, 223, 186, 1, 140, 231, 95, 80, 193, 176, 152, - 147, 181, 254, 105, 77, 65, 0, 0, 9, 1, 97, 71, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 1; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.x = -2700356.0349524925; - test_msg.y = -4292510.187605589; - test_msg.z = 3855357.4185667858; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2700356.03495 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2700356.03495, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4292510.18761 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4292510.18761, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3855357.41857 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3855357.41857, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 246, 215, 32, 220, 46, 39, 0, 216, 41, 227, 254, - 33, 154, 68, 193, 9, 151, 154, 124, 231, 95, 80, 193, 1, 183, - 214, 139, 255, 105, 77, 65, 0, 0, 9, 0, 7, 98, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.x = -2700355.9913074784; - test_msg.y = -4292509.946935424; - test_msg.z = 3855359.0924900775; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2700355.99131 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2700355.99131, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4292509.94694 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4292509.94694, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3855359.09249 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3855359.09249, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 212, 157, 67, 24, 153, 222, 105, 1, - 252, 161, 68, 193, 254, 247, 52, 112, 74, 67, 80, 193, 164, 207, - 47, 146, 44, 163, 77, 65, 0, 0, 8, 0, 145, 4, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084500; - test_msg.x = -2704376.0110433814; - test_msg.y = -4263209.753232954; - test_msg.z = 3884633.142084079; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704376.01104 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704376.01104, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263209.75323 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263209.75323, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884633.14208 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884633.14208, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +class Testauto_check_sbp_navigation_MsgPosECEFDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEFDepA1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.x, -2700356.3285146747); + assign(test_msg_.y, -4292509.928737887); + assign(test_msg_.z, 3855357.5011712564); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 56, 158, 67, 24, 215, 184, 223, 246, - 251, 161, 68, 193, 36, 126, 17, 39, 74, 67, 80, 193, 19, 179, - 70, 80, 44, 163, 77, 65, 0, 0, 8, 0, 245, 66, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084600; - test_msg.x = -2704375.9287024545; - test_msg.y = -4263208.610442672; - test_msg.z = 3884632.627157578; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084600) - << "incorrect value for last_msg_.tow, expected 407084600, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704375.9287 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704375.9287, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263208.61044 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263208.61044, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884632.62716 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884632.62716, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 156, 158, 67, 24, 73, 74, 214, 148, - 251, 161, 68, 193, 213, 151, 184, 215, 73, 67, 80, 193, 110, 99, - 38, 164, 43, 163, 77, 65, 0, 0, 8, 0, 5, 223, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084700; - test_msg.x = -2704375.162789617; - test_msg.y = -4263207.370641668; - test_msg.z = 3884631.282421521; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084700) - << "incorrect value for last_msg_.tow, expected 407084700, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704375.16279 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704375.16279, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263207.37064 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263207.37064, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884631.28242 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884631.28242, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 0, 159, 67, 24, 177, 111, 112, 45, - 252, 161, 68, 193, 213, 168, 198, 253, 73, 67, 80, 193, 245, 12, - 228, 12, 44, 163, 77, 65, 0, 0, 8, 0, 143, 212, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084800; - test_msg.x = -2704376.3549937834; - test_msg.y = -4263207.965250214; - test_msg.z = 3884632.1007095524; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084800) - << "incorrect value for last_msg_.tow, expected 407084800, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704376.35499 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704376.35499, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263207.96525 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263207.96525, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884632.10071 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884632.10071, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 100, 159, 67, 24, 67, 231, 72, 165, - 251, 161, 68, 193, 150, 210, 36, 212, 73, 67, 80, 193, 234, 33, - 25, 189, 43, 163, 77, 65, 0, 0, 8, 0, 70, 221, + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084900; - test_msg.x = -2704375.291287334; - test_msg.y = -4263207.314747473; - test_msg.z = 3884631.4773294823; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084900) - << "incorrect value for last_msg_.tow, expected 407084900, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704375.29129 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704375.29129, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263207.31475 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263207.31475, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884631.47733 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884631.47733, is " - << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgPosECEFDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosECEFDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8f4b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 0, 2, 195, 4, 32, 46, 162, 68, 24, 224, 72, 131, 215, - 251, 161, 68, 193, 180, 123, 222, 94, 74, 67, 80, 193, 191, 3, - 131, 193, 45, 163, 77, 65, 0, 0, 5, 0, 17, 221, + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 246, 215, 32, 20, 46, 39, 0, 212, 196, 12, 42, + 34, 154, 68, 193, 9, 113, 112, 123, 231, 95, 80, 193, 54, 97, + 38, 192, 254, 105, 77, 65, 0, 0, 9, 1, 75, 143, }; + uint8_t encoded_payload_[32] = { + 20, 46, 39, 0, 212, 196, 12, 42, 34, 154, 68, 193, 9, 113, 112, 123, + 231, 95, 80, 193, 54, 97, 38, 192, 254, 105, 77, 65, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; - sbp_msg_pos_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 5; - test_msg.tow = 407151150; - test_msg.x = -2704375.68369399; - test_msg.y = -4263209.482329298; - test_msg.z = 3884635.5118107493; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 5) - << "incorrect value for last_msg_.n_sats, expected 5, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407151150) - << "incorrect value for last_msg_.tow, expected 407151150, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2704375.68369 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2704375.68369, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4263209.48233 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4263209.48233, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3884635.51181 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3884635.51181, is " - << last_msg_.z; + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.x, -2700357.485576801); + assign(test_msg_.y, -4292509.80414865); + assign(test_msg_.z, 3855356.517968082); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x71cc; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 246, 215, 32, 120, 46, 39, 0, 112, 97, 39, 190, + 34, 154, 68, 193, 230, 43, 119, 115, 231, 95, 80, 193, 50, 199, + 76, 66, 254, 105, 77, 65, 0, 0, 9, 0, 204, 113, + }; + uint8_t encoded_payload_[32] = { + 120, 46, 39, 0, 112, 97, 39, 190, 34, 154, 68, 193, 230, 43, 119, 115, + 231, 95, 80, 193, 50, 199, 76, 66, 254, 105, 77, 65, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 1); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.x, -2700356.0349524925); + assign(test_msg_.y, -4292510.187605589); + assign(test_msg_.z, 3855357.4185667858); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x4761; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 246, 215, 32, 120, 46, 39, 0, 194, 82, 121, 4, + 34, 154, 68, 193, 223, 186, 1, 140, 231, 95, 80, 193, 176, 152, + 147, 181, 254, 105, 77, 65, 0, 0, 9, 1, 97, 71, + }; + uint8_t encoded_payload_[32] = { + 120, 46, 39, 0, 194, 82, 121, 4, 34, 154, 68, 193, 223, 186, 1, 140, + 231, 95, 80, 193, 176, 152, 147, 181, 254, 105, 77, 65, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA4() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.x, -2700355.9913074784); + assign(test_msg_.y, -4292509.946935424); + assign(test_msg_.z, 3855359.0924900775); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x6207; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 246, 215, 32, 220, 46, 39, 0, 216, 41, 227, 254, + 33, 154, 68, 193, 9, 151, 154, 124, 231, 95, 80, 193, 1, 183, + 214, 139, 255, 105, 77, 65, 0, 0, 9, 0, 7, 98, + }; + uint8_t encoded_payload_[32] = { + 220, 46, 39, 0, 216, 41, 227, 254, 33, 154, 68, 193, 9, 151, 154, 124, + 231, 95, 80, 193, 1, 183, 214, 139, 255, 105, 77, 65, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA5() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084500); + assign(test_msg_.x, -2704376.0110433814); + assign(test_msg_.y, -4263209.753232954); + assign(test_msg_.z, 3884633.142084079); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x491; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 212, 157, 67, 24, 153, 222, 105, 1, + 252, 161, 68, 193, 254, 247, 52, 112, 74, 67, 80, 193, 164, 207, + 47, 146, 44, 163, 77, 65, 0, 0, 8, 0, 145, 4, + }; + uint8_t encoded_payload_[32] = { + 212, 157, 67, 24, 153, 222, 105, 1, 252, 161, 68, + 193, 254, 247, 52, 112, 74, 67, 80, 193, 164, 207, + 47, 146, 44, 163, 77, 65, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA6() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084600); + assign(test_msg_.x, -2704375.9287024545); + assign(test_msg_.y, -4263208.610442672); + assign(test_msg_.z, 3884632.627157578); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x42f5; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 56, 158, 67, 24, 215, 184, 223, 246, + 251, 161, 68, 193, 36, 126, 17, 39, 74, 67, 80, 193, 19, 179, + 70, 80, 44, 163, 77, 65, 0, 0, 8, 0, 245, 66, + }; + uint8_t encoded_payload_[32] = { + 56, 158, 67, 24, 215, 184, 223, 246, 251, 161, 68, 193, 36, 126, 17, 39, + 74, 67, 80, 193, 19, 179, 70, 80, 44, 163, 77, 65, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA7() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084700); + assign(test_msg_.x, -2704375.162789617); + assign(test_msg_.y, -4263207.370641668); + assign(test_msg_.z, 3884631.282421521); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xdf05; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 156, 158, 67, 24, 73, 74, 214, 148, + 251, 161, 68, 193, 213, 151, 184, 215, 73, 67, 80, 193, 110, 99, + 38, 164, 43, 163, 77, 65, 0, 0, 8, 0, 5, 223, + }; + uint8_t encoded_payload_[32] = { + 156, 158, 67, 24, 73, 74, 214, 148, 251, 161, 68, + 193, 213, 151, 184, 215, 73, 67, 80, 193, 110, 99, + 38, 164, 43, 163, 77, 65, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA8() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084800); + assign(test_msg_.x, -2704376.3549937834); + assign(test_msg_.y, -4263207.965250214); + assign(test_msg_.z, 3884632.1007095524); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xd48f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 0, 159, 67, 24, 177, 111, 112, 45, + 252, 161, 68, 193, 213, 168, 198, 253, 73, 67, 80, 193, 245, 12, + 228, 12, 44, 163, 77, 65, 0, 0, 8, 0, 143, 212, + }; + uint8_t encoded_payload_[32] = { + 0, 159, 67, 24, 177, 111, 112, 45, 252, 161, 68, + 193, 213, 168, 198, 253, 73, 67, 80, 193, 245, 12, + 228, 12, 44, 163, 77, 65, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA9 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA9() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084900); + assign(test_msg_.x, -2704375.291287334); + assign(test_msg_.y, -4263207.314747473); + assign(test_msg_.z, 3884631.4773294823); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xdd46; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 100, 159, 67, 24, 67, 231, 72, 165, + 251, 161, 68, 193, 150, 210, 36, 212, 73, 67, 80, 193, 234, 33, + 25, 189, 43, 163, 77, 65, 0, 0, 8, 0, 70, 221, + }; + uint8_t encoded_payload_[32] = { + 100, 159, 67, 24, 67, 231, 72, 165, 251, 161, 68, + 193, 150, 210, 36, 212, 73, 67, 80, 193, 234, 33, + 25, 189, 43, 163, 77, 65, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosECEFDepA10 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosECEFDepA10() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 5); + assign(test_msg_.tow, 407151150); + assign(test_msg_.x, -2704375.68369399); + assign(test_msg_.y, -4263209.482329298); + assign(test_msg_.z, 3884635.5118107493); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_dep_a, + sizeof(msg->pos_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xdd11; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_ecef_dep_a_t &lesser, + const sbp_msg_pos_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { + 85, 0, 2, 195, 4, 32, 46, 162, 68, 24, 224, 72, 131, 215, + 251, 161, 68, 193, 180, 123, 222, 94, 74, 67, 80, 193, 191, 3, + 131, 193, 45, 163, 77, 65, 0, 0, 5, 0, 17, 221, + }; + uint8_t encoded_payload_[32] = { + 46, 162, 68, 24, 224, 72, 131, 215, 251, 161, 68, 193, 180, 123, 222, 94, + 74, 67, 80, 193, 191, 3, 131, 193, 45, 163, 77, 65, 0, 0, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ( + sbp_msg_pos_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_pos_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFGNSS.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFGNSS.cc index fa042d8875..2226dff98e 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFGNSS.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosECEFGNSS.cc @@ -16,111 +16,618 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosECEFGNSS0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosECEFGNSS0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosECEFGNSS0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosECEFGNSS0() { + assign(test_msg_.accuracy, 182); + assign(test_msg_.flags, 4); + assign(test_msg_.n_sats, 18); + assign(test_msg_.tow, 501867800); + assign(test_msg_.x, -2694229.7079770807); + assign(test_msg_.y, -4264073.427345817); + assign(test_msg_.z, 3890655.013186158); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_ecef_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosEcefGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_ecef_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosEcefGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_ecef_gnss, + sizeof(msg->pos_ecef_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_ecef_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_ecef_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosEcefGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0x287; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 32; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_ecef_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_ecef_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_ecef_gnss_t &lesser, + const sbp_msg_pos_ecef_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_ecef_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_ecef_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_ecef_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosEcefGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosEcefGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosEcefGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosECEFGNSS0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_ecef_gnss_t test_msg_{}; + uint8_t encoded_frame_[32 + 8] = { 85, 41, 2, 0, 16, 32, 24, 229, 233, 29, 52, 254, 158, 218, 42, 142, 68, 193, 69, 162, 89, 91, 34, 68, 80, 193, 131, 21, 176, 129, 239, 174, 77, 65, 182, 0, 18, 4, 135, 2, }; + uint8_t encoded_payload_[32] = { + 24, 229, 233, 29, 52, 254, 158, 218, 42, 142, 68, + 193, 69, 162, 89, 91, 34, 68, 80, 193, 131, 21, + 176, 129, 239, 174, 77, 65, 182, 0, 18, 4, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_ecef_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosEcefGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosEcefGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[32]; - sbp_msg_pos_ecef_gnss_t test_msg{}; - test_msg.accuracy = 182; - test_msg.flags = 4; - test_msg.n_sats = 18; - test_msg.tow = 501867800; - test_msg.x = -2694229.7079770807; - test_msg.y = -4264073.427345817; - test_msg.z = 3890655.013186158; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 182) - << "incorrect value for last_msg_.accuracy, expected 182, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 4) - << "incorrect value for last_msg_.flags, expected 4, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 18) - << "incorrect value for last_msg_.n_sats, expected 18, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; - EXPECT_LT((last_msg_.x * 100 - -2694229.70798 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2694229.70798, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4264073.42735 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4264073.42735, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3890655.01319 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3890655.01319, is " - << last_msg_.z; + EXPECT_EQ(sbp_msg_pos_ecef_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); } +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + + for (uint8_t i = 0; i < 32; i++) { + EXPECT_EQ(sbp_msg_pos_ecef_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosEcefGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_ecef_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosEcefGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_ecef_gnss_t lesser = info.test_msg; + sbp_msg_pos_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosEcefGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_ECEF_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_ecef_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_ecef_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_ecef_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_ecef_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[32]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 32); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 32), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_ecef_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 32); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosEcefGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosECEFGNSS0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosEcefGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLH.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLH.cc index 0f9c667411..062b8c6e4b 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLH.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLH.cc @@ -16,551 +16,2989 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosLLH0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosLLH0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLLH0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLLH0() { + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 28.21160739227208); + assign(test_msg_.lat, 37.25130398358085); + assign(test_msg_.lon, -121.87505366879361); + assign(test_msg_.n_sats, 14); + assign(test_msg_.tow, 326825000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlh, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlh); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh, sizeof(msg->pos_llh)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlh); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xa2af; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_t &lesser, + const sbp_msg_pos_llh_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLH0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { 85, 10, 2, 211, 136, 34, 40, 244, 122, 19, 201, 106, 155, 186, 42, 160, 66, 64, 168, 109, 26, 225, 0, 120, 94, 192, 130, 102, 237, 230, 43, 54, 60, 64, 0, 0, 0, 0, 14, 2, 175, 162, }; + uint8_t encoded_payload_[34] = { + 40, 244, 122, 19, 201, 106, 155, 186, 42, 160, 66, 64, + 168, 109, 26, 225, 0, 120, 94, 192, 130, 102, 237, 230, + 43, 54, 60, 64, 0, 0, 0, 0, 14, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlh, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosLlh, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlh, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlh, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlh); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_LLH"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_pos_llh_t test_msg{}; - test_msg.flags = 2; - test_msg.h_accuracy = 0; - test_msg.height = 28.21160739227208; - test_msg.lat = 37.25130398358085; - test_msg.lon = -121.87505366879361; - test_msg.n_sats = 14; - test_msg.tow = 326825000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 28.2116073923 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 28.2116073923, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.2513039836 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.2513039836, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -121.875053669 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -121.875053669, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 14) - << "incorrect value for last_msg_.n_sats, expected 14, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLH1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlh, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosLlh, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLH1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLLH1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLLH1() { + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 27.742055560866373); + assign(test_msg_.lat, 37.251303074738104); + assign(test_msg_.lon, -121.87505349618341); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlh, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlh); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh, sizeof(msg->pos_llh)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlh); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xb126; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_t &lesser, + const sbp_msg_pos_llh_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLH1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { 85, 10, 2, 211, 136, 34, 16, 248, 122, 19, 52, 177, 251, 178, 42, 160, 66, 64, 237, 22, 97, 224, 0, 120, 94, 192, 107, 188, 109, 90, 247, 189, 59, 64, 0, 0, 0, 0, 15, 2, 38, 177, }; + uint8_t encoded_payload_[34] = { + 16, 248, 122, 19, 52, 177, 251, 178, 42, 160, 66, 64, + 237, 22, 97, 224, 0, 120, 94, 192, 107, 188, 109, 90, + 247, 189, 59, 64, 0, 0, 0, 0, 15, 2, + }; +}; - sbp_msg_pos_llh_t test_msg{}; - test_msg.flags = 2; - test_msg.h_accuracy = 0; - test_msg.height = 27.742055560866373; - test_msg.lat = 37.251303074738104; - test_msg.lon = -121.87505349618341; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 27.7420555609 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 27.7420555609, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.2513030747 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.2513030747, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -121.875053496 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -121.875053496, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLH2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLH2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlh, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosLlh, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLH2, Test) { - uint8_t encoded_frame[] = { - 85, 10, 2, 211, 136, 34, 248, 251, 122, 19, 135, 66, 9, 163, - 42, 160, 66, 64, 146, 8, 99, 225, 0, 120, 94, 192, 45, 181, - 143, 219, 28, 157, 59, 64, 0, 0, 0, 0, 15, 2, 51, 40, - }; + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_pos_llh_t test_msg{}; - test_msg.flags = 2; - test_msg.h_accuracy = 0; - test_msg.height = 27.613721582970516; - test_msg.lat = 37.25130117370741; - test_msg.lon = -121.87505373641241; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 27.613721583 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 27.613721583, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.2513011737 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.2513011737, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -121.875053736 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -121.875053736, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLH3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLH3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlh, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLH3, Test) { - uint8_t encoded_frame[] = { - 85, 10, 2, 211, 136, 34, 224, 255, 122, 19, 18, 44, 253, 119, - 42, 160, 66, 64, 48, 109, 39, 231, 0, 120, 94, 192, 185, 76, - 48, 17, 119, 205, 59, 64, 0, 0, 0, 0, 15, 2, 12, 194, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_pos_llh_t test_msg{}; - test_msg.flags = 2; - test_msg.h_accuracy = 0; - test_msg.height = 27.80259807042305; - test_msg.lat = 37.251296042079176; - test_msg.lon = -121.87505511141057; - test_msg.n_sats = 15; - test_msg.tow = 326828000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 27.8025980704 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 27.8025980704, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.2512960421 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.2512960421, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -121.875055111 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -121.875055111, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326828000) - << "incorrect value for last_msg_.tow, expected 326828000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLH4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLH4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLH4, Test) { - uint8_t encoded_frame[] = { - 85, 10, 2, 211, 136, 34, 200, 3, 123, 19, 225, 237, 238, 90, - 42, 160, 66, 64, 59, 143, 70, 235, 0, 120, 94, 192, 101, 106, - 249, 224, 131, 240, 59, 64, 0, 0, 0, 0, 15, 2, 34, 103, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlh, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_llh_t test_msg{}; - test_msg.flags = 2; - test_msg.h_accuracy = 0; - test_msg.height = 27.939512310879213; - test_msg.lat = 37.251292578377395; - test_msg.lon = -121.87505609407974; - test_msg.n_sats = 15; - test_msg.tow = 326829000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 27.9395123109 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 27.9395123109, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.2512925784 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.2512925784, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -121.875056094 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -121.875056094, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326829000) - << "incorrect value for last_msg_.tow, expected 326829000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } } + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlh); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_LLH"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlh, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosLlh, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLH2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLH2() { + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 27.613721582970516); + assign(test_msg_.lat, 37.25130117370741); + assign(test_msg_.lon, -121.87505373641241); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlh, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlh); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh, sizeof(msg->pos_llh)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlh); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x2833; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_t &lesser, + const sbp_msg_pos_llh_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 10, 2, 211, 136, 34, 248, 251, 122, 19, 135, 66, 9, 163, + 42, 160, 66, 64, 146, 8, 99, 225, 0, 120, 94, 192, 45, 181, + 143, 219, 28, 157, 59, 64, 0, 0, 0, 0, 15, 2, 51, 40, + }; + uint8_t encoded_payload_[34] = { + 248, 251, 122, 19, 135, 66, 9, 163, 42, 160, 66, 64, + 146, 8, 99, 225, 0, 120, 94, 192, 45, 181, 143, 219, + 28, 157, 59, 64, 0, 0, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlh, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosLlh, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlh, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlh, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlh); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_LLH"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlh, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosLlh, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLH3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLH3() { + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 27.80259807042305); + assign(test_msg_.lat, 37.251296042079176); + assign(test_msg_.lon, -121.87505511141057); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326828000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlh, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlh); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh, sizeof(msg->pos_llh)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlh); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xc20c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_t &lesser, + const sbp_msg_pos_llh_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 10, 2, 211, 136, 34, 224, 255, 122, 19, 18, 44, 253, 119, + 42, 160, 66, 64, 48, 109, 39, 231, 0, 120, 94, 192, 185, 76, + 48, 17, 119, 205, 59, 64, 0, 0, 0, 0, 15, 2, 12, 194, + }; + uint8_t encoded_payload_[34] = { + 224, 255, 122, 19, 18, 44, 253, 119, 42, 160, 66, 64, + 48, 109, 39, 231, 0, 120, 94, 192, 185, 76, 48, 17, + 119, 205, 59, 64, 0, 0, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlh, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosLlh, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlh, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlh, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlh); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_LLH"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlh, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosLlh, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLH4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLH4() { + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 27.939512310879213); + assign(test_msg_.lat, 37.251292578377395); + assign(test_msg_.lon, -121.87505609407974); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326829000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlh, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlh); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh, sizeof(msg->pos_llh)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlh); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x6722; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_t &lesser, + const sbp_msg_pos_llh_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgPosLlh, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgPosLlh, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 10, 2, 211, 136, 34, 200, 3, 123, 19, 225, 237, 238, 90, + 42, 160, 66, 64, 59, 143, 70, 235, 0, 120, 94, 192, 101, 106, + 249, 224, 131, 240, 59, 64, 0, 0, 0, 0, 15, 2, 34, 103, + }; + uint8_t encoded_payload_[34] = { + 200, 3, 123, 19, 225, 237, 238, 90, 42, 160, 66, 64, + 59, 143, 70, 235, 0, 120, 94, 192, 101, 106, 249, 224, + 131, 240, 59, 64, 0, 0, 0, 0, 15, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlh, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgPosLlh, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ( + sbp_msg_pos_llh_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlh, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlh, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_t lesser = info.test_msg; + sbp_msg_pos_llh_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlh); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_POS_LLH"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlh, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLH4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgPosLlh, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHCov.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHCov.cc index e5339490e1..db63cd2b59 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHCov.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHCov.cc @@ -16,131 +16,646 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosLLHCov0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosLLHCov0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLLHCov0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLLHCov0() { + assign(test_msg_.cov_d_d, 2.0); + assign(test_msg_.cov_e_d, 1.0); + assign(test_msg_.cov_e_e, 6.0); + assign(test_msg_.cov_n_d, 8.0); + assign(test_msg_.cov_n_e, 5.0); + assign(test_msg_.cov_n_n, 7.0); + assign(test_msg_.flags, 5); + assign(test_msg_.height, 0.0); + assign(test_msg_.lat, 0.0); + assign(test_msg_.lon, 7.0); + assign(test_msg_.n_sats, 5); + assign(test_msg_.tow, 7); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_cov_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_cov_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhCov, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_cov_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhCov); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_cov, sizeof(msg->pos_llh_cov)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_cov_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_cov, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhCov); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x6297; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 54; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_cov_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_cov_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_cov_t &lesser, + const sbp_msg_pos_llh_cov_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cov_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cov_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cov_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cov_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhCov, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhCov, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhCov, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhCov, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHCov0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_cov_t test_msg_{}; + uint8_t encoded_frame_[54 + 8] = { 85, 17, 2, 66, 0, 54, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 64, 0, 0, 160, 64, 0, 0, 0, 65, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 5, 5, 151, 98, }; + uint8_t encoded_payload_[54] = { + 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 28, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 224, 64, 0, 0, 160, 64, + 0, 0, 0, 65, 0, 0, 192, 64, 0, 0, 128, 63, 0, 0, 0, 64, 5, 5, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_cov_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhCov, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_cov_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhCov, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + EXPECT_EQ( + sbp_msg_pos_llh_cov_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + for (uint8_t i = 0; i < 54; i++) { + EXPECT_EQ(sbp_msg_pos_llh_cov_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_cov_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhCov, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_cov_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_cov_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_cov_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhCov, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_llh_cov_t test_msg{}; - test_msg.cov_d_d = 2.0; - test_msg.cov_e_d = 1.0; - test_msg.cov_e_e = 6.0; - test_msg.cov_n_d = 8.0; - test_msg.cov_n_e = 5.0; - test_msg.cov_n_n = 7.0; - test_msg.flags = 5; - test_msg.height = 0.0; - test_msg.lat = 0.0; - test_msg.lon = 7.0; - test_msg.n_sats = 5; - test_msg.tow = 7; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_d_d * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_d_d, expected 2.0, is " - << last_msg_.cov_d_d; - EXPECT_LT((last_msg_.cov_e_d * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_d, expected 1.0, is " - << last_msg_.cov_e_d; - EXPECT_LT((last_msg_.cov_e_e * 100 - 6.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_e, expected 6.0, is " - << last_msg_.cov_e_e; - EXPECT_LT((last_msg_.cov_n_d * 100 - 8.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_d, expected 8.0, is " - << last_msg_.cov_n_d; - EXPECT_LT((last_msg_.cov_n_e * 100 - 5.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_e, expected 5.0, is " - << last_msg_.cov_n_e; - EXPECT_LT((last_msg_.cov_n_n * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_n, expected 7.0, is " - << last_msg_.cov_n_n; - EXPECT_EQ(last_msg_.flags, 5) - << "incorrect value for last_msg_.flags, expected 5, is " - << last_msg_.flags; - EXPECT_LT((last_msg_.height * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 0.0, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 0.0, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected 7.0, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 5) - << "incorrect value for last_msg_.n_sats, expected 5, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 7) - << "incorrect value for last_msg_.tow, expected 7, is " << last_msg_.tow; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_d_d, greater.cov_d_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_d, greater.cov_e_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_e, greater.cov_e_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_d, greater.cov_n_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_e, greater.cov_n_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_n, greater.cov_n_n); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgPosLlhCov); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_COV"); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_cov_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_cov_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_cov, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_cov, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhCov, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHCov0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhCov, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHDepA.cc index 17826e7e15..737a759fb1 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosLLHDepA.cc @@ -16,1205 +16,6724 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosLLHDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosLLHDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLLHDepA0() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 69.80437675175607); + assign(test_msg_.lat, 37.42906890908121); + assign(test_msg_.lon, -122.17338662202773); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8bec; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { 85, 1, 2, 246, 215, 34, 20, 46, 39, 0, 250, 29, 226, 186, 235, 182, 66, 64, 19, 203, 51, 196, 24, 139, 94, 192, 31, 157, 160, 232, 122, 115, 81, 64, 0, 0, 0, 0, 9, 0, 236, 139, }; + uint8_t encoded_payload_[34] = { + 20, 46, 39, 0, 250, 29, 226, 186, 235, 182, 66, 64, + 19, 203, 51, 196, 24, 139, 94, 192, 31, 157, 160, 232, + 122, 115, 81, 64, 0, 0, 0, 0, 9, 0, + }; +}; - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 69.80437675175607; - test_msg.lat = 37.42906890908121; - test_msg.lon = -122.17338662202773; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 69.8043767518 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 69.8043767518, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.4290689091 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.4290689091, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.173386622 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.173386622, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 246, 215, 34, 20, 46, 39, 0, 161, 51, 75, 148, - 235, 182, 66, 64, 36, 41, 246, 30, 25, 139, 94, 192, 254, 218, - 49, 127, 10, 108, 81, 64, 0, 0, 0, 0, 9, 1, 25, 117, - }; + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.height = 69.68814067715354; - test_msg.lat = 37.42906430885274; - test_msg.lon = -122.17340826071865; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 69.6881406772 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 69.6881406772, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.4290643089 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.4290643089, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.173408261 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.173408261, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 246, 215, 34, 120, 46, 39, 0, 56, 214, 210, 65, - 235, 182, 66, 64, 13, 46, 132, 80, 25, 139, 94, 192, 22, 143, - 46, 234, 191, 95, 81, 64, 0, 0, 0, 0, 9, 0, 174, 105, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 69.49608854815264; - test_msg.lat = 37.42905447764173; - test_msg.lon = -122.17342007549469; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 69.4960885482 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 69.4960885482, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.4290544776 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.4290544776, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.173420075 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.173420075, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 246, 215, 34, 120, 46, 39, 0, 251, 117, 115, 140, - 235, 182, 66, 64, 152, 134, 167, 12, 25, 139, 94, 192, 160, 22, - 137, 253, 4, 108, 81, 64, 0, 0, 0, 0, 9, 1, 122, 127, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 1; - test_msg.h_accuracy = 0; - test_msg.height = 69.68780458819901; - test_msg.lat = 37.429063373925565; - test_msg.lon = -122.17340389594972; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 69.6878045882 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 69.6878045882, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.4290633739 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.4290633739, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.173403896 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.173403896, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 246, 215, 34, 220, 46, 39, 0, 51, 124, 88, 251, - 235, 182, 66, 64, 153, 5, 250, 16, 25, 139, 94, 192, 146, 60, - 187, 219, 152, 161, 81, 64, 0, 0, 0, 0, 9, 0, 194, 158, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 70.5249547317965; - test_msg.lat = 37.42907659359516; - test_msg.lon = -122.17340492645452; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 70.5249547318 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 70.5249547318, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.4290765936 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.4290765936, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.173404926 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.173404926, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 212, 157, 67, 24, 8, 23, 228, 8, - 151, 225, 66, 64, 156, 174, 42, 194, 230, 152, 94, 192, 153, 23, - 72, 47, 196, 40, 16, 64, 0, 0, 0, 0, 8, 0, 237, 169, - }; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 4.039810885214956; - test_msg.lat = 37.76242171418386; - test_msg.lon = -122.38908437889262; - test_msg.n_sats = 8; - test_msg.tow = 407084500; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 4.03981088521 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 4.03981088521, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.7624217142 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.7624217142, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389084379 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389084379, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLLHDepA1() { + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 69.68814067715354); + assign(test_msg_.lat, 37.42906430885274); + assign(test_msg_.lon, -122.17340826071865); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.v_accuracy, 0); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 56, 158, 67, 24, 220, 109, 212, 24, - 151, 225, 66, 64, 159, 231, 254, 219, 230, 152, 94, 192, 128, 151, - 67, 19, 233, 105, 7, 64, 0, 0, 0, 0, 8, 0, 152, 11, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 2.926714087009657; - test_msg.lat = 37.76242361423985; - test_msg.lon = -122.38909053700489; - test_msg.n_sats = 8; - test_msg.tow = 407084600; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 2.92671408701 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 2.92671408701, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.7624236142 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.7624236142, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389090537 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389090537, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084600) - << "incorrect value for last_msg_.tow, expected 407084600, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 156, 158, 67, 24, 13, 91, 237, 11, - 151, 225, 66, 64, 75, 113, 210, 220, 230, 152, 94, 192, 37, 6, - 145, 188, 89, 112, 238, 63, 0, 0, 0, 0, 8, 0, 221, 155, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 0.9512146647395566; - test_msg.lat = 37.762422076126406; - test_msg.lon = -122.3890907340148; - test_msg.n_sats = 8; - test_msg.tow = 407084700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 0.95121466474 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 0.95121466474, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.7624220761 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.7624220761, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389090734 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389090734, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084700) - << "incorrect value for last_msg_.tow, expected 407084700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 0, 159, 67, 24, 51, 183, 5, 8, - 151, 225, 66, 64, 13, 226, 148, 253, 230, 152, 94, 192, 187, 27, - 11, 32, 69, 213, 2, 64, 0, 0, 0, 0, 8, 0, 82, 94, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 2.354135752047538; - test_msg.lat = 37.762421610632735; - test_msg.lon = -122.38909854449612; - test_msg.n_sats = 8; - test_msg.tow = 407084800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 2.35413575205 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 2.35413575205, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.7624216106 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.7624216106, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389098544 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389098544, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084800) - << "incorrect value for last_msg_.tow, expected 407084800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 100, 159, 67, 24, 22, 77, 146, 22, - 151, 225, 66, 64, 64, 134, 105, 227, 230, 152, 94, 192, 37, 99, - 114, 72, 31, 103, 241, 63, 0, 0, 0, 0, 8, 0, 70, 60, + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 1.0876763181642641; - test_msg.lat = 37.76242334502801; - test_msg.lon = -122.38909230523223; - test_msg.n_sats = 8; - test_msg.tow = 407084900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 1.08767631816 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 1.08767631816, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.762423345 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.762423345, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389092305 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389092305, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084900) - << "incorrect value for last_msg_.tow, expected 407084900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgPosLLHDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgPosLLHDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x7519; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgPosLLHDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 1, 2, 195, 4, 34, 46, 162, 68, 24, 124, 245, 46, 169, - 151, 225, 66, 64, 135, 149, 234, 187, 230, 152, 94, 192, 194, 201, - 115, 145, 166, 175, 20, 64, 0, 0, 0, 0, 5, 0, 212, 121, + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 246, 215, 34, 20, 46, 39, 0, 161, 51, 75, 148, + 235, 182, 66, 64, 36, 41, 246, 30, 25, 139, 94, 192, 254, 218, + 49, 127, 10, 108, 81, 64, 0, 0, 0, 0, 9, 1, 25, 117, + }; + uint8_t encoded_payload_[34] = { + 20, 46, 39, 0, 161, 51, 75, 148, 235, 182, 66, 64, + 36, 41, 246, 30, 25, 139, 94, 192, 254, 218, 49, 127, + 10, 108, 81, 64, 0, 0, 0, 0, 9, 1, }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_pos_llh_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.height = 5.171533844654222; - test_msg.lat = 37.76244082253376; - test_msg.lon = -122.38908288868525; - test_msg.n_sats = 5; - test_msg.tow = 407151150; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - 5.17153384465 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 5.17153384465, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.7624408225 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.7624408225, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.389082889 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.389082889, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 5) - << "incorrect value for last_msg_.n_sats, expected 5, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407151150) - << "incorrect value for last_msg_.tow, expected 407151150, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } } + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA2() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 69.49608854815264); + assign(test_msg_.lat, 37.42905447764173); + assign(test_msg_.lon, -122.17342007549469); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x69ae; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 246, 215, 34, 120, 46, 39, 0, 56, 214, 210, 65, + 235, 182, 66, 64, 13, 46, 132, 80, 25, 139, 94, 192, 22, 143, + 46, 234, 191, 95, 81, 64, 0, 0, 0, 0, 9, 0, 174, 105, + }; + uint8_t encoded_payload_[34] = { + 120, 46, 39, 0, 56, 214, 210, 65, 235, 182, 66, 64, + 13, 46, 132, 80, 25, 139, 94, 192, 22, 143, 46, 234, + 191, 95, 81, 64, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA3() { + assign(test_msg_.flags, 1); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 69.68780458819901); + assign(test_msg_.lat, 37.429063373925565); + assign(test_msg_.lon, -122.17340389594972); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x7f7a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 246, 215, 34, 120, 46, 39, 0, 251, 117, 115, 140, + 235, 182, 66, 64, 152, 134, 167, 12, 25, 139, 94, 192, 160, 22, + 137, 253, 4, 108, 81, 64, 0, 0, 0, 0, 9, 1, 122, 127, + }; + uint8_t encoded_payload_[34] = { + 120, 46, 39, 0, 251, 117, 115, 140, 235, 182, 66, 64, + 152, 134, 167, 12, 25, 139, 94, 192, 160, 22, 137, 253, + 4, 108, 81, 64, 0, 0, 0, 0, 9, 1, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA4() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 70.5249547317965); + assign(test_msg_.lat, 37.42907659359516); + assign(test_msg_.lon, -122.17340492645452); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x9ec2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 246, 215, 34, 220, 46, 39, 0, 51, 124, 88, 251, + 235, 182, 66, 64, 153, 5, 250, 16, 25, 139, 94, 192, 146, 60, + 187, 219, 152, 161, 81, 64, 0, 0, 0, 0, 9, 0, 194, 158, + }; + uint8_t encoded_payload_[34] = { + 220, 46, 39, 0, 51, 124, 88, 251, 235, 182, 66, 64, + 153, 5, 250, 16, 25, 139, 94, 192, 146, 60, 187, 219, + 152, 161, 81, 64, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA5() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 4.039810885214956); + assign(test_msg_.lat, 37.76242171418386); + assign(test_msg_.lon, -122.38908437889262); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084500); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xa9ed; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 212, 157, 67, 24, 8, 23, 228, 8, + 151, 225, 66, 64, 156, 174, 42, 194, 230, 152, 94, 192, 153, 23, + 72, 47, 196, 40, 16, 64, 0, 0, 0, 0, 8, 0, 237, 169, + }; + uint8_t encoded_payload_[34] = { + 212, 157, 67, 24, 8, 23, 228, 8, 151, 225, 66, 64, + 156, 174, 42, 194, 230, 152, 94, 192, 153, 23, 72, 47, + 196, 40, 16, 64, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA6() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 2.926714087009657); + assign(test_msg_.lat, 37.76242361423985); + assign(test_msg_.lon, -122.38909053700489); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084600); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xb98; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 56, 158, 67, 24, 220, 109, 212, 24, + 151, 225, 66, 64, 159, 231, 254, 219, 230, 152, 94, 192, 128, 151, + 67, 19, 233, 105, 7, 64, 0, 0, 0, 0, 8, 0, 152, 11, + }; + uint8_t encoded_payload_[34] = { + 56, 158, 67, 24, 220, 109, 212, 24, 151, 225, 66, 64, + 159, 231, 254, 219, 230, 152, 94, 192, 128, 151, 67, 19, + 233, 105, 7, 64, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA7() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 0.9512146647395566); + assign(test_msg_.lat, 37.762422076126406); + assign(test_msg_.lon, -122.3890907340148); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x9bdd; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 156, 158, 67, 24, 13, 91, 237, 11, + 151, 225, 66, 64, 75, 113, 210, 220, 230, 152, 94, 192, 37, 6, + 145, 188, 89, 112, 238, 63, 0, 0, 0, 0, 8, 0, 221, 155, + }; + uint8_t encoded_payload_[34] = { + 156, 158, 67, 24, 13, 91, 237, 11, 151, 225, 66, 64, + 75, 113, 210, 220, 230, 152, 94, 192, 37, 6, 145, 188, + 89, 112, 238, 63, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA8() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 2.354135752047538); + assign(test_msg_.lat, 37.762421610632735); + assign(test_msg_.lon, -122.38909854449612); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084800); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x5e52; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 0, 159, 67, 24, 51, 183, 5, 8, + 151, 225, 66, 64, 13, 226, 148, 253, 230, 152, 94, 192, 187, 27, + 11, 32, 69, 213, 2, 64, 0, 0, 0, 0, 8, 0, 82, 94, + }; + uint8_t encoded_payload_[34] = { + 0, 159, 67, 24, 51, 183, 5, 8, 151, 225, 66, 64, + 13, 226, 148, 253, 230, 152, 94, 192, 187, 27, 11, 32, + 69, 213, 2, 64, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA9 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA9() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 1.0876763181642641); + assign(test_msg_.lat, 37.76242334502801); + assign(test_msg_.lon, -122.38909230523223); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x3c46; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 100, 159, 67, 24, 22, 77, 146, 22, + 151, 225, 66, 64, 64, 134, 105, 227, 230, 152, 94, 192, 37, 99, + 114, 72, 31, 103, 241, 63, 0, 0, 0, 0, 8, 0, 70, 60, + }; + uint8_t encoded_payload_[34] = { + 100, 159, 67, 24, 22, 77, 146, 22, 151, 225, 66, 64, + 64, 134, 105, 227, 230, 152, 94, 192, 37, 99, 114, 72, + 31, 103, 241, 63, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgPosLLHDepA10 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgPosLLHDepA10() { + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.height, 5.171533844654222); + assign(test_msg_.lat, 37.76244082253376); + assign(test_msg_.lon, -122.38908288868525); + assign(test_msg_.n_sats, 5); + assign(test_msg_.tow, 407151150); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_dep_a, + sizeof(msg->pos_llh_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x79d4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_pos_llh_dep_a_t &lesser, + const sbp_msg_pos_llh_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_dep_a_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { + 85, 1, 2, 195, 4, 34, 46, 162, 68, 24, 124, 245, 46, 169, + 151, 225, 66, 64, 135, 149, 234, 187, 230, 152, 94, 192, 194, 201, + 115, 145, 166, 175, 20, 64, 0, 0, 0, 0, 5, 0, 212, 121, + }; + uint8_t encoded_payload_[34] = { + 46, 162, 68, 24, 124, 245, 46, 169, 151, 225, 66, 64, + 135, 149, 234, 187, 230, 152, 94, 192, 194, 201, 115, 145, + 166, 175, 20, 64, 0, 0, 0, 0, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_dep_a_t lesser = info.test_msg; + sbp_msg_pos_llh_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLLHDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhCovGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhCovGnss.cc index e013d8865b..d51ff9ac7d 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhCovGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhCovGnss.cc @@ -16,135 +16,663 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosLlhCovGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosLlhCovGnss0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLlhCovGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLlhCovGnss0() { + assign(test_msg_.cov_d_d, 0.03288137540221214); + assign(test_msg_.cov_e_d, -0.0008439270895905793); + assign(test_msg_.cov_e_e, 0.004523798823356628); + assign(test_msg_.cov_n_d, 0.0018563168123364449); + assign(test_msg_.cov_n_e, -0.00036755966721102595); + assign(test_msg_.cov_n_n, 0.007488971576094627); + assign(test_msg_.flags, 4); + assign(test_msg_.height, -17.39382124780135); + assign(test_msg_.lat, 37.83123196497633); + assign(test_msg_.lon, -122.28650381011681); + assign(test_msg_.n_sats, 18); + assign(test_msg_.tow, 501867800); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_cov_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_cov_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhCovGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_cov_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhCovGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_cov_gnss, + sizeof(msg->pos_llh_cov_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_cov_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_cov_gnss, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhCovGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0xc40a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 54; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_cov_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_cov_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_cov_gnss_t &lesser, + const sbp_msg_pos_llh_cov_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_cov_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_cov_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhCovGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgPosLlhCovGnss, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhCovGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhCovGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLlhCovGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_cov_gnss_t test_msg_{}; + uint8_t encoded_frame_[54 + 8] = { 85, 49, 2, 0, 16, 54, 24, 229, 233, 29, 73, 123, 28, 207, 101, 234, 66, 64, 100, 168, 19, 20, 86, 146, 94, 192, 214, 198, 35, 120, 209, 100, 49, 192, 12, 102, 245, 59, 6, 181, 192, 185, 168, 79, 243, 58, 96, 60, 148, 59, 253, 58, 93, 186, 159, 174, 6, 61, 18, 4, 10, 196, }; + uint8_t encoded_payload_[54] = { + 24, 229, 233, 29, 73, 123, 28, 207, 101, 234, 66, 64, 100, 168, + 19, 20, 86, 146, 94, 192, 214, 198, 35, 120, 209, 100, 49, 192, + 12, 102, 245, 59, 6, 181, 192, 185, 168, 79, 243, 58, 96, 60, + 148, 59, 253, 58, 93, 186, 159, 174, 6, 61, 18, 4, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgPosLlhCovGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhCovGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + + for (uint8_t i = 0; i < 54; i++) { + EXPECT_EQ( + sbp_msg_pos_llh_cov_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhCovGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_cov_gnss_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhCovGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_pos_llh_cov_gnss_t test_msg{}; - test_msg.cov_d_d = 0.03288137540221214; - test_msg.cov_e_d = -0.0008439270895905793; - test_msg.cov_e_e = 0.004523798823356628; - test_msg.cov_n_d = 0.0018563168123364449; - test_msg.cov_n_e = -0.00036755966721102595; - test_msg.cov_n_n = 0.007488971576094627; - test_msg.flags = 4; - test_msg.height = -17.39382124780135; - test_msg.lat = 37.83123196497633; - test_msg.lon = -122.28650381011681; - test_msg.n_sats = 18; - test_msg.tow = 501867800; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_d_d * 100 - 0.0328813754022 * 100), 0.05) - << "incorrect value for last_msg_.cov_d_d, expected 0.0328813754022, is " - << last_msg_.cov_d_d; - EXPECT_LT((last_msg_.cov_e_d * 100 - -0.000843927089591 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_d, expected -0.000843927089591, " - "is " - << last_msg_.cov_e_d; - EXPECT_LT((last_msg_.cov_e_e * 100 - 0.00452379882336 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_e, expected 0.00452379882336, is " - << last_msg_.cov_e_e; - EXPECT_LT((last_msg_.cov_n_d * 100 - 0.00185631681234 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_d, expected 0.00185631681234, is " - << last_msg_.cov_n_d; - EXPECT_LT((last_msg_.cov_n_e * 100 - -0.000367559667211 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_e, expected -0.000367559667211, " - "is " - << last_msg_.cov_n_e; - EXPECT_LT((last_msg_.cov_n_n * 100 - 0.00748897157609 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_n, expected 0.00748897157609, is " - << last_msg_.cov_n_n; - EXPECT_EQ(last_msg_.flags, 4) - << "incorrect value for last_msg_.flags, expected 4, is " - << last_msg_.flags; - EXPECT_LT((last_msg_.height * 100 - -17.3938212478 * 100), 0.05) - << "incorrect value for last_msg_.height, expected -17.3938212478, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.831231965 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.831231965, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.28650381 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.28650381, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 18) - << "incorrect value for last_msg_.n_sats, expected 18, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_d_d, greater.cov_d_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_d, greater.cov_e_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_e, greater.cov_e_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_d, greater.cov_n_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_e, greater.cov_n_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_n, greater.cov_n_n); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_cov_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhCovGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_COV_GNSS"); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_cov_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_cov_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_cov_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.pos_llh_cov_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[54]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 54); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 54), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 54); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhCovGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhCovGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhCovGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhGnss.cc index 371cfbec57..97b73069c2 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPosLlhGnss.cc @@ -16,115 +16,622 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPosLlhGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPosLlhGnss0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPosLlhGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPosLlhGnss0() { + assign(test_msg_.flags, 4); + assign(test_msg_.h_accuracy, 87); + assign(test_msg_.height, -17.39382124780135); + assign(test_msg_.lat, 37.83123196497633); + assign(test_msg_.lon, -122.28650381011681); + assign(test_msg_.n_sats, 18); + assign(test_msg_.tow, 501867800); + assign(test_msg_.v_accuracy, 181); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pos_llh_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPosLlhGnss, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pos_llh_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPosLlhGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pos_llh_gnss, + sizeof(msg->pos_llh_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pos_llh_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pos_llh_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPosLlhGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0x3769; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pos_llh_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pos_llh_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pos_llh_gnss_t &lesser, + const sbp_msg_pos_llh_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_pos_llh_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pos_llh_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pos_llh_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pos_llh_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhGnss, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPosLlhGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPosLlhGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPosLlhGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgPosLlhGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pos_llh_gnss_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { 85, 42, 2, 0, 16, 34, 24, 229, 233, 29, 73, 123, 28, 207, 101, 234, 66, 64, 100, 168, 19, 20, 86, 146, 94, 192, 214, 198, 35, 120, 209, 100, 49, 192, 87, 0, 181, 0, 18, 4, 105, 55, }; + uint8_t encoded_payload_[34] = { + 24, 229, 233, 29, 73, 123, 28, 207, 101, 234, 66, 64, + 100, 168, 19, 20, 86, 146, 94, 192, 214, 198, 35, 120, + 209, 100, 49, 192, 87, 0, 181, 0, 18, 4, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pos_llh_gnss_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPosLlhGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pos_llh_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPosLlhGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + EXPECT_EQ(sbp_msg_pos_llh_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_pos_llh_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pos_llh_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPosLlhGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_pos_llh_gnss_t test_msg{}; - test_msg.flags = 4; - test_msg.h_accuracy = 87; - test_msg.height = -17.39382124780135; - test_msg.lat = 37.83123196497633; - test_msg.lon = -122.28650381011681; - test_msg.n_sats = 18; - test_msg.tow = 501867800; - test_msg.v_accuracy = 181; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 4) - << "incorrect value for last_msg_.flags, expected 4, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 87) - << "incorrect value for last_msg_.h_accuracy, expected 87, is " - << last_msg_.h_accuracy; - EXPECT_LT((last_msg_.height * 100 - -17.3938212478 * 100), 0.05) - << "incorrect value for last_msg_.height, expected -17.3938212478, is " - << last_msg_.height; - EXPECT_LT((last_msg_.lat * 100 - 37.831231965 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 37.831231965, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - -122.28650381 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected -122.28650381, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.n_sats, 18) - << "incorrect value for last_msg_.n_sats, expected 18, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 181) - << "incorrect value for last_msg_.v_accuracy, expected 181, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_pos_llh_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_pos_llh_gnss_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pos_llh_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPosLlhGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_pos_llh_gnss_t lesser = info.test_msg; + sbp_msg_pos_llh_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPosLlhGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POS_LLH_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pos_llh_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pos_llh_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pos_llh_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pos_llh_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pos_llh_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPosLlhGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPosLlhGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPosLlhGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgPoseRelative.cc b/c/test/cpp/auto_check_sbp_navigation_MsgPoseRelative.cc index b2933e5870..13a7974062 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgPoseRelative.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgPoseRelative.cc @@ -16,66 +16,302 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgPoseRelative0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgPoseRelative0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgPoseRelative0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgPoseRelative0() { + assign(test_msg_.cov_c_x_x, 2.0); + assign(test_msg_.cov_c_x_y, 0.0); + assign(test_msg_.cov_c_x_z, 0.0); + assign(test_msg_.cov_c_y_y, 2.0); + assign(test_msg_.cov_c_y_z, 0.0); + assign(test_msg_.cov_c_z_z, 2.0); + assign(test_msg_.cov_r_x_x, 1.0); + assign(test_msg_.cov_r_x_y, 0.0); + assign(test_msg_.cov_r_x_z, 0.0); + assign(test_msg_.cov_r_y_y, 1.0); + assign(test_msg_.cov_r_y_z, 0.0); + assign(test_msg_.cov_r_z_z, 1.0); + assign(test_msg_.flags, 5); + assign(test_msg_.sensor_id, 0); + assign(test_msg_.timestamp_1, 1110); + assign(test_msg_.timestamp_2, 2220); + assign(test_msg_.tow, 1110); + + assign(test_msg_.trans[0], 1100); + + assign(test_msg_.trans[1], 550); + + assign(test_msg_.trans[2], 100); + assign(test_msg_.w, -859307164); + assign(test_msg_.x, -6444804); + assign(test_msg_.y, -1866844813); + assign(test_msg_.z, 622997694); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_pose_relative_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_pose_relative_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgPoseRelative, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_pose_relative_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgPoseRelative); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->pose_relative, + sizeof(msg->pose_relative)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_pose_relative_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.pose_relative, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgPoseRelative); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xBBAB; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 90; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_pose_relative_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_pose_relative_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_pose_relative_t &lesser, + const sbp_msg_pose_relative_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgPoseRelative0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_msg_pose_relative_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_pose_relative_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_pose_relative_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_pose_relative_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgPoseRelative, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgPoseRelative, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgPoseRelative, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgPoseRelative, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_pose_relative_t test_msg_{}; + uint8_t encoded_frame_[90 + 8] = { 85, 69, 2, 66, 0, 90, 86, 4, 0, 0, 0, 86, 4, 0, 0, 172, 8, 0, 0, 76, 4, 0, 0, 38, 2, 0, 0, 100, 0, 0, 0, 100, 3, 200, 204, 252, 168, 157, 255, 115, 53, 186, @@ -84,118 +320,446 @@ TEST_F(Test_auto_check_sbp_navigation_MsgPoseRelative0, Test) { 63, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 5, 171, 187, }; + uint8_t encoded_payload_[90] = { + 86, 4, 0, 0, 0, 86, 4, 0, 0, 172, 8, 0, 0, 76, 4, + 0, 0, 38, 2, 0, 0, 100, 0, 0, 0, 100, 3, 200, 204, 252, + 168, 157, 255, 115, 53, 186, 144, 190, 48, 34, 37, 0, 0, 128, 63, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 63, 0, 0, 0, + 0, 0, 0, 128, 63, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 64, 5, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_pose_relative_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgPoseRelative, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[90]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_pose_relative_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 90); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 90), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgPoseRelative, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 90); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 90), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[90]; + + EXPECT_EQ(sbp_msg_pose_relative_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 90), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[90]; + + for (uint8_t i = 0; i < 90; i++) { + EXPECT_EQ(sbp_msg_pose_relative_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pose_relative_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_pose_relative_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 90); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgPoseRelative, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 90); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_pose_relative_t msg{}; + + EXPECT_EQ(sbp_msg_pose_relative_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_pose_relative_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_pose_relative_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_pose_relative_t test_msg{}; - test_msg.cov_c_x_x = 2.0; - test_msg.cov_c_x_y = 0.0; - test_msg.cov_c_x_z = 0.0; - test_msg.cov_c_y_y = 2.0; - test_msg.cov_c_y_z = 0.0; - test_msg.cov_c_z_z = 2.0; - test_msg.cov_r_x_x = 1.0; - test_msg.cov_r_x_y = 0.0; - test_msg.cov_r_x_z = 0.0; - test_msg.cov_r_y_y = 1.0; - test_msg.cov_r_y_z = 0.0; - test_msg.cov_r_z_z = 1.0; - test_msg.flags = 5; - test_msg.sensor_id = 0; - test_msg.timestamp_1 = 1110; - test_msg.timestamp_2 = 2220; - test_msg.tow = 1110; - - test_msg.trans[0] = 1100; - - test_msg.trans[1] = 550; - - test_msg.trans[2] = 100; - test_msg.w = -859307164; - test_msg.x = -6444804; - test_msg.y = -1866844813; - test_msg.z = 622997694; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_c_x_x * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_x_x, expected 2.0, is " - << last_msg_.cov_c_x_x; - EXPECT_LT((last_msg_.cov_c_x_y * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_x_y, expected 0.0, is " - << last_msg_.cov_c_x_y; - EXPECT_LT((last_msg_.cov_c_x_z * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_x_z, expected 0.0, is " - << last_msg_.cov_c_x_z; - EXPECT_LT((last_msg_.cov_c_y_y * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_y_y, expected 2.0, is " - << last_msg_.cov_c_y_y; - EXPECT_LT((last_msg_.cov_c_y_z * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_y_z, expected 0.0, is " - << last_msg_.cov_c_y_z; - EXPECT_LT((last_msg_.cov_c_z_z * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_c_z_z, expected 2.0, is " - << last_msg_.cov_c_z_z; - EXPECT_LT((last_msg_.cov_r_x_x * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_x_x, expected 1.0, is " - << last_msg_.cov_r_x_x; - EXPECT_LT((last_msg_.cov_r_x_y * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_x_y, expected 0.0, is " - << last_msg_.cov_r_x_y; - EXPECT_LT((last_msg_.cov_r_x_z * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_x_z, expected 0.0, is " - << last_msg_.cov_r_x_z; - EXPECT_LT((last_msg_.cov_r_y_y * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_y_y, expected 1.0, is " - << last_msg_.cov_r_y_y; - EXPECT_LT((last_msg_.cov_r_y_z * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_y_z, expected 0.0, is " - << last_msg_.cov_r_y_z; - EXPECT_LT((last_msg_.cov_r_z_z * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_r_z_z, expected 1.0, is " - << last_msg_.cov_r_z_z; - EXPECT_EQ(last_msg_.flags, 5) - << "incorrect value for last_msg_.flags, expected 5, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.sensor_id, 0) - << "incorrect value for last_msg_.sensor_id, expected 0, is " - << last_msg_.sensor_id; - EXPECT_EQ(last_msg_.timestamp_1, 1110) - << "incorrect value for last_msg_.timestamp_1, expected 1110, is " - << last_msg_.timestamp_1; - EXPECT_EQ(last_msg_.timestamp_2, 2220) - << "incorrect value for last_msg_.timestamp_2, expected 2220, is " - << last_msg_.timestamp_2; - EXPECT_EQ(last_msg_.tow, 1110) - << "incorrect value for last_msg_.tow, expected 1110, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.trans[0], 1100) - << "incorrect value for last_msg_.trans[0], expected 1100, is " - << last_msg_.trans[0]; - EXPECT_EQ(last_msg_.trans[1], 550) - << "incorrect value for last_msg_.trans[1], expected 550, is " - << last_msg_.trans[1]; - EXPECT_EQ(last_msg_.trans[2], 100) - << "incorrect value for last_msg_.trans[2], expected 100, is " - << last_msg_.trans[2]; - EXPECT_EQ(last_msg_.w, -859307164) - << "incorrect value for last_msg_.w, expected -859307164, is " - << last_msg_.w; - EXPECT_EQ(last_msg_.x, -6444804) - << "incorrect value for last_msg_.x, expected -6444804, is " - << last_msg_.x; - EXPECT_EQ(last_msg_.y, -1866844813) - << "incorrect value for last_msg_.y, expected -1866844813, is " - << last_msg_.y; - EXPECT_EQ(last_msg_.z, 622997694) - << "incorrect value for last_msg_.z, expected 622997694, is " - << last_msg_.z; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_pose_relative_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgPoseRelative, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_x_x, greater.cov_c_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_x_y, greater.cov_c_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_x_z, greater.cov_c_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_y_y, greater.cov_c_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_y_z, greater.cov_c_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_c_z_z, greater.cov_c_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_x_x, greater.cov_r_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_x_y, greater.cov_r_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_x_z, greater.cov_r_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_y_y, greater.cov_r_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_y_z, greater.cov_r_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.cov_r_z_z, greater.cov_r_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.sensor_id, greater.sensor_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.timestamp_1, greater.timestamp_1); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.timestamp_2, greater.timestamp_2); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.trans[0], greater.trans[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.trans[1], greater.trans[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.trans[2], greater.trans[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_pose_relative_t lesser = info.test_msg; + sbp_msg_pose_relative_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgPoseRelative); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_POSE_RELATIVE"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_pose_relative_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_pose_relative_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.pose_relative, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.pose_relative, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[90]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 90); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 90), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_pose_relative_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 90); + EXPECT_EQ(msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgPoseRelative, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgPoseRelative0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgPoseRelative, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgProtectionLevel.cc b/c/test/cpp/auto_check_sbp_navigation_MsgProtectionLevel.cc index 26749ca8be..d1e4b58707 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgProtectionLevel.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgProtectionLevel.cc @@ -16,109 +16,635 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgProtectionLevel0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgProtectionLevel0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgProtectionLevel0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgProtectionLevel0() { + assign(test_msg_.flags, 0); + assign(test_msg_.height, 0.0); + assign(test_msg_.hpl, 0); + assign(test_msg_.lat, 0.0); + assign(test_msg_.lon, 0.0); + assign(test_msg_.tow, 501867400); + assign(test_msg_.vpl, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_protection_level_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_protection_level_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgProtectionLevelDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_protection_level_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgProtectionLevelDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->protection_level_dep_a, + sizeof(msg->protection_level_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_protection_level_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.protection_level_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgProtectionLevelDepA); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0xc352; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 33; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_protection_level_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_protection_level_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_protection_level_dep_a_t &lesser, + const sbp_msg_protection_level_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_protection_level_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_protection_level_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_protection_level_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_protection_level_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgProtectionLevelDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgProtectionLevelDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgProtectionLevelDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgProtectionLevelDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgProtectionLevel0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_protection_level_dep_a_t test_msg_{}; + uint8_t encoded_frame_[33 + 8] = { 85, 22, 2, 0, 16, 33, 136, 227, 233, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 82, 195, }; + uint8_t encoded_payload_[33] = { + 136, 227, 233, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_protection_level_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgProtectionLevelDepA, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_protection_level_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgProtectionLevelDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[33]; - sbp_msg_protection_level_dep_a_t test_msg{}; - test_msg.flags = 0; - test_msg.height = 0.0; - test_msg.hpl = 0; - test_msg.lat = 0.0; - test_msg.lon = 0.0; - test_msg.tow = 501867400; - test_msg.vpl = 0; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_LT((last_msg_.height * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.height, expected 0.0, is " - << last_msg_.height; - EXPECT_EQ(last_msg_.hpl, 0) - << "incorrect value for last_msg_.hpl, expected 0, is " << last_msg_.hpl; - EXPECT_LT((last_msg_.lat * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.lat, expected 0.0, is " - << last_msg_.lat; - EXPECT_LT((last_msg_.lon * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.lon, expected 0.0, is " - << last_msg_.lon; - EXPECT_EQ(last_msg_.tow, 501867400) - << "incorrect value for last_msg_.tow, expected 501867400, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.vpl, 0) - << "incorrect value for last_msg_.vpl, expected 0, is " << last_msg_.vpl; + EXPECT_EQ(sbp_msg_protection_level_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); } +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + + for (uint8_t i = 0; i < 33; i++) { + EXPECT_EQ(sbp_msg_protection_level_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_protection_level_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_protection_level_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgProtectionLevelDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_protection_level_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_protection_level_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_protection_level_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_protection_level_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_protection_level_dep_a_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgProtectionLevelDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.height, greater.height); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.hpl, greater.hpl); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lat, greater.lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.lon, greater.lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_protection_level_dep_a_t lesser = info.test_msg; + sbp_msg_protection_level_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.vpl, greater.vpl); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgProtectionLevelDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_PROTECTION_LEVEL_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_protection_level_dep_a_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_protection_level_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.protection_level_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.protection_level_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_protection_level_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgProtectionLevelDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgProtectionLevel0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgProtectionLevelDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgReferenceFrameParam.cc b/c/test/cpp/auto_check_sbp_navigation_MsgReferenceFrameParam.cc index 5b11ca773a..1961a09acb 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgReferenceFrameParam.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgReferenceFrameParam.cc @@ -16,66 +16,314 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgReferenceFrameParam0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgReferenceFrameParam0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgReferenceFrameParam0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgReferenceFrameParam0() { + assign(test_msg_.delta_X0, 7); + assign(test_msg_.delta_Y0, 8); + assign(test_msg_.delta_Z0, 9); + assign(test_msg_.dot_delta_X0, 14); + assign(test_msg_.dot_delta_Y0, 15); + assign(test_msg_.dot_delta_Z0, 16); + assign(test_msg_.dot_scale, 20); + assign(test_msg_.dot_theta_01, 17); + assign(test_msg_.dot_theta_02, 18); + assign(test_msg_.dot_theta_03, 19); + assign(test_msg_.re_t0, 6); + assign(test_msg_.scale, 13); + assign(test_msg_.sin, 4); + { + const char assign_string[] = { + (char)102, (char)111, (char)111, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.sn, assign_string, sizeof(assign_string)); + } + assign(test_msg_.ssr_iod, 1); + assign(test_msg_.theta_01, 10); + assign(test_msg_.theta_02, 11); + assign(test_msg_.theta_03, 12); + { + const char assign_string[] = { + (char)98, (char)97, (char)114, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.tn, assign_string, sizeof(assign_string)); + } + assign(test_msg_.utn, 5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_reference_frame_param_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_reference_frame_param_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgReferenceFrameParam, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_reference_frame_param_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgReferenceFrameParam); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->reference_frame_param, + sizeof(msg->reference_frame_param)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_reference_frame_param_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.reference_frame_param, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgReferenceFrameParam); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xA106; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 124; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_reference_frame_param_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_reference_frame_param_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_reference_frame_param_t &lesser, + const sbp_msg_reference_frame_param_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_reference_frame_param_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_reference_frame_param_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_reference_frame_param_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_reference_frame_param_cmp(&greater, &lesser), 0); -TEST_F(Test_auto_check_sbp_navigation_MsgReferenceFrameParam0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_message_cmp(SbpMsgReferenceFrameParam, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgReferenceFrameParam, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgReferenceFrameParam, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgReferenceFrameParam, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_reference_frame_param_t test_msg_{}; + uint8_t encoded_frame_[124 + 8] = { 85, 68, 2, 66, 0, 124, 1, 102, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 97, 114, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -85,129 +333,438 @@ TEST_F(Test_auto_check_sbp_navigation_MsgReferenceFrameParam0, Test) { 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, 6, 161, }; + uint8_t encoded_payload_[124] = { + 1, 102, 111, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 97, 114, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 0, 6, 0, 7, 0, + 0, 0, 8, 0, 0, 0, 9, 0, 0, 0, 10, 0, 0, 0, 11, 0, 0, 0, + 12, 0, 0, 0, 13, 0, 0, 0, 14, 0, 0, 0, 15, 0, 0, 0, 16, 0, + 0, 0, 17, 0, 0, 0, 18, 0, 0, 0, 19, 0, 0, 0, 20, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_reference_frame_param_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgReferenceFrameParam, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[124]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_reference_frame_param_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 124); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 124), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgReferenceFrameParam, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 124); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 124), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[124]; + + EXPECT_EQ(sbp_msg_reference_frame_param_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 124), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[124]; + + for (uint8_t i = 0; i < 124; i++) { + EXPECT_EQ(sbp_msg_reference_frame_param_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_reference_frame_param_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_reference_frame_param_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 124); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgReferenceFrameParam, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 124); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_reference_frame_param_t msg{}; + + EXPECT_EQ(sbp_msg_reference_frame_param_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_reference_frame_param_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_reference_frame_param_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - sbp_msg_reference_frame_param_t test_msg{}; - test_msg.delta_X0 = 7; - test_msg.delta_Y0 = 8; - test_msg.delta_Z0 = 9; - test_msg.dot_delta_X0 = 14; - test_msg.dot_delta_Y0 = 15; - test_msg.dot_delta_Z0 = 16; - test_msg.dot_scale = 20; - test_msg.dot_theta_01 = 17; - test_msg.dot_theta_02 = 18; - test_msg.dot_theta_03 = 19; - test_msg.re_t0 = 6; - test_msg.scale = 13; - test_msg.sin = 4; - { - const char assign_string[] = { - (char)102, (char)111, (char)111, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.sn, assign_string, sizeof(assign_string)); - } - test_msg.ssr_iod = 1; - test_msg.theta_01 = 10; - test_msg.theta_02 = 11; - test_msg.theta_03 = 12; - { - const char assign_string[] = { - (char)98, (char)97, (char)114, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.tn, assign_string, sizeof(assign_string)); - } - test_msg.utn = 5; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.delta_X0, 7) - << "incorrect value for last_msg_.delta_X0, expected 7, is " - << last_msg_.delta_X0; - EXPECT_EQ(last_msg_.delta_Y0, 8) - << "incorrect value for last_msg_.delta_Y0, expected 8, is " - << last_msg_.delta_Y0; - EXPECT_EQ(last_msg_.delta_Z0, 9) - << "incorrect value for last_msg_.delta_Z0, expected 9, is " - << last_msg_.delta_Z0; - EXPECT_EQ(last_msg_.dot_delta_X0, 14) - << "incorrect value for last_msg_.dot_delta_X0, expected 14, is " - << last_msg_.dot_delta_X0; - EXPECT_EQ(last_msg_.dot_delta_Y0, 15) - << "incorrect value for last_msg_.dot_delta_Y0, expected 15, is " - << last_msg_.dot_delta_Y0; - EXPECT_EQ(last_msg_.dot_delta_Z0, 16) - << "incorrect value for last_msg_.dot_delta_Z0, expected 16, is " - << last_msg_.dot_delta_Z0; - EXPECT_EQ(last_msg_.dot_scale, 20) - << "incorrect value for last_msg_.dot_scale, expected 20, is " - << last_msg_.dot_scale; - EXPECT_EQ(last_msg_.dot_theta_01, 17) - << "incorrect value for last_msg_.dot_theta_01, expected 17, is " - << last_msg_.dot_theta_01; - EXPECT_EQ(last_msg_.dot_theta_02, 18) - << "incorrect value for last_msg_.dot_theta_02, expected 18, is " - << last_msg_.dot_theta_02; - EXPECT_EQ(last_msg_.dot_theta_03, 19) - << "incorrect value for last_msg_.dot_theta_03, expected 19, is " - << last_msg_.dot_theta_03; - EXPECT_EQ(last_msg_.re_t0, 6) - << "incorrect value for last_msg_.re_t0, expected 6, is " - << last_msg_.re_t0; - EXPECT_EQ(last_msg_.scale, 13) - << "incorrect value for last_msg_.scale, expected 13, is " - << last_msg_.scale; - EXPECT_EQ(last_msg_.sin, 4) - << "incorrect value for last_msg_.sin, expected 4, is " << last_msg_.sin; - { - const char check_string[] = { - (char)102, (char)111, (char)111, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.sn, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.sn, expected string '" << check_string - << "', is '" << last_msg_.sn << "'"; - } - EXPECT_EQ(last_msg_.ssr_iod, 1) - << "incorrect value for last_msg_.ssr_iod, expected 1, is " - << last_msg_.ssr_iod; - EXPECT_EQ(last_msg_.theta_01, 10) - << "incorrect value for last_msg_.theta_01, expected 10, is " - << last_msg_.theta_01; - EXPECT_EQ(last_msg_.theta_02, 11) - << "incorrect value for last_msg_.theta_02, expected 11, is " - << last_msg_.theta_02; - EXPECT_EQ(last_msg_.theta_03, 12) - << "incorrect value for last_msg_.theta_03, expected 12, is " - << last_msg_.theta_03; - { - const char check_string[] = { - (char)98, (char)97, (char)114, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.tn, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.tn, expected string '" << check_string - << "', is '" << last_msg_.tn << "'"; - } - EXPECT_EQ(last_msg_.utn, 5) - << "incorrect value for last_msg_.utn, expected 5, is " << last_msg_.utn; + EXPECT_EQ(sbp_msg_reference_frame_param_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgReferenceFrameParam, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.delta_X0, greater.delta_X0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.delta_Y0, greater.delta_Y0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.delta_Z0, greater.delta_Z0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_delta_X0, greater.dot_delta_X0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_delta_Y0, greater.dot_delta_Y0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_delta_Z0, greater.dot_delta_Z0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_scale, greater.dot_scale); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_theta_01, greater.dot_theta_01); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_theta_02, greater.dot_theta_02); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.dot_theta_03, greater.dot_theta_03); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.re_t0, greater.re_t0); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.scale, greater.scale); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.sin, greater.sin); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.sn, greater.sn); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod, greater.ssr_iod); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.theta_01, greater.theta_01); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.theta_02, greater.theta_02); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.theta_03, greater.theta_03); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.tn, greater.tn); + comparison_tests(lesser, greater); + } + { + sbp_msg_reference_frame_param_t lesser = info.test_msg; + sbp_msg_reference_frame_param_t greater = info.test_msg; + make_lesser_greater(lesser.utn, greater.utn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgReferenceFrameParam); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_REFERENCE_FRAME_PARAM"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_reference_frame_param_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_reference_frame_param_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.reference_frame_param, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.reference_frame_param, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[124]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 124); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 124), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_reference_frame_param_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 124); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgReferenceFrameParam, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgReferenceFrameParam0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgReferenceFrameParam, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgUTCLeapSecond.cc b/c/test/cpp/auto_check_sbp_navigation_MsgUTCLeapSecond.cc index 16181641f9..658d74aed6 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgUTCLeapSecond.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgUTCLeapSecond.cc @@ -16,117 +16,635 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgUTCLeapSecond0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgUTCLeapSecond0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgUTCLeapSecond0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgUTCLeapSecond0() { + assign(test_msg_.count_after, 9); + assign(test_msg_.count_before, 4); + assign(test_msg_.ref_dn, 8); + assign(test_msg_.ref_wn, 7); + assign(test_msg_.reserved_0, 1); + assign(test_msg_.reserved_1, 2); + assign(test_msg_.reserved_2, 3); + assign(test_msg_.reserved_3, 5); + assign(test_msg_.reserved_4, 6); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_leap_second_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_utc_leap_second_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUtcLeapSecond, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_leap_second_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUtcLeapSecond); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->utc_leap_second, + sizeof(msg->utc_leap_second)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_utc_leap_second_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.utc_leap_second, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUtcLeapSecond); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xE832; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 14; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_utc_leap_second_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_utc_leap_second_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_utc_leap_second_t &lesser, + const sbp_msg_utc_leap_second_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_utc_leap_second_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_utc_leap_second_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_utc_leap_second_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_utc_leap_second_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUtcLeapSecond, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUtcLeapSecond, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUtcLeapSecond, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUtcLeapSecond, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_navigation_MsgUTCLeapSecond0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_utc_leap_second_t test_msg_{}; + uint8_t encoded_frame_[14 + 8] = { 85, 58, 2, 66, 0, 14, 1, 0, 2, 0, 3, 4, 5, 0, 6, 0, 7, 0, 8, 9, 50, 232, }; + uint8_t encoded_payload_[14] = { + 1, 0, 2, 0, 3, 4, 5, 0, 6, 0, 7, 0, 8, 9, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_utc_leap_second_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUtcLeapSecond, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_utc_leap_second_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUtcLeapSecond, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + EXPECT_EQ(sbp_msg_utc_leap_second_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + + for (uint8_t i = 0; i < 14; i++) { + EXPECT_EQ( + sbp_msg_utc_leap_second_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_leap_second_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_utc_leap_second_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUtcLeapSecond, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_utc_leap_second_t msg{}; - sbp_msg_utc_leap_second_t test_msg{}; - test_msg.count_after = 9; - test_msg.count_before = 4; - test_msg.ref_dn = 8; - test_msg.ref_wn = 7; - test_msg.reserved_0 = 1; - test_msg.reserved_1 = 2; - test_msg.reserved_2 = 3; - test_msg.reserved_3 = 5; - test_msg.reserved_4 = 6; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.count_after, 9) - << "incorrect value for last_msg_.count_after, expected 9, is " - << last_msg_.count_after; - EXPECT_EQ(last_msg_.count_before, 4) - << "incorrect value for last_msg_.count_before, expected 4, is " - << last_msg_.count_before; - EXPECT_EQ(last_msg_.ref_dn, 8) - << "incorrect value for last_msg_.ref_dn, expected 8, is " - << last_msg_.ref_dn; - EXPECT_EQ(last_msg_.ref_wn, 7) - << "incorrect value for last_msg_.ref_wn, expected 7, is " - << last_msg_.ref_wn; - EXPECT_EQ(last_msg_.reserved_0, 1) - << "incorrect value for last_msg_.reserved_0, expected 1, is " - << last_msg_.reserved_0; - EXPECT_EQ(last_msg_.reserved_1, 2) - << "incorrect value for last_msg_.reserved_1, expected 2, is " - << last_msg_.reserved_1; - EXPECT_EQ(last_msg_.reserved_2, 3) - << "incorrect value for last_msg_.reserved_2, expected 3, is " - << last_msg_.reserved_2; - EXPECT_EQ(last_msg_.reserved_3, 5) - << "incorrect value for last_msg_.reserved_3, expected 5, is " - << last_msg_.reserved_3; - EXPECT_EQ(last_msg_.reserved_4, 6) - << "incorrect value for last_msg_.reserved_4, expected 6, is " - << last_msg_.reserved_4; + EXPECT_EQ(sbp_msg_utc_leap_second_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_utc_leap_second_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_utc_leap_second_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_utc_leap_second_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUtcLeapSecond, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.count_after, greater.count_after); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.count_before, greater.count_before); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.ref_dn, greater.ref_dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.ref_wn, greater.ref_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.reserved_0, greater.reserved_0); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.reserved_1, greater.reserved_1); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.reserved_2, greater.reserved_2); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.reserved_3, greater.reserved_3); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_leap_second_t lesser = info.test_msg; + sbp_msg_utc_leap_second_t greater = info.test_msg; + make_lesser_greater(lesser.reserved_4, greater.reserved_4); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUtcLeapSecond); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UTC_LEAP_SECOND"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_utc_leap_second_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_utc_leap_second_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.utc_leap_second, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.utc_leap_second, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[14]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 14); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 14), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_leap_second_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 14); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUtcLeapSecond, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCLeapSecond0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUtcLeapSecond, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgUTCTime.cc b/c/test/cpp/auto_check_sbp_navigation_MsgUTCTime.cc index ba9dac766f..3a3dde7aca 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgUTCTime.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgUTCTime.cc @@ -16,117 +16,615 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgUTCTime0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgUTCTime0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgUTCTime0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgUTCTime0() { + assign(test_msg_.day, 9); + assign(test_msg_.flags, 1); + assign(test_msg_.hours, 19); + assign(test_msg_.minutes, 24); + assign(test_msg_.month, 4); + assign(test_msg_.ns, 800000000); + assign(test_msg_.seconds, 9); + assign(test_msg_.tow, 501867800); + assign(test_msg_.year, 2021); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_time_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_utc_time_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUtcTime, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_time_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUtcTime); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->utc_time, sizeof(msg->utc_time)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_utc_time_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.utc_time, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUtcTime); + info.sender_id = 789; + info.preamble = 0x55; + info.crc = 0xfdc7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_utc_time_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_utc_time_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_utc_time_t &lesser, + const sbp_msg_utc_time_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_utc_time_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_utc_time_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_utc_time_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_utc_time_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgUtcTime, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgUtcTime, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgUtcTime, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgUtcTime, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_navigation_MsgUTCTime0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_utc_time_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 3, 1, 21, 3, 16, 1, 24, 229, 233, 29, 229, 7, 4, 9, 19, 24, 9, 0, 8, 175, 47, 199, 253, }; + uint8_t encoded_payload_[16] = { + 1, 24, 229, 233, 29, 229, 7, 4, 9, 19, 24, 9, 0, 8, 175, 47, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_utc_time_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgUtcTime, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_utc_time_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgUtcTime, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ( + sbp_msg_utc_time_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ(sbp_msg_utc_time_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_utc_time_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUtcTime, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_t msg{}; - sbp_msg_utc_time_t test_msg{}; - test_msg.day = 9; - test_msg.flags = 1; - test_msg.hours = 19; - test_msg.minutes = 24; - test_msg.month = 4; - test_msg.ns = 800000000; - test_msg.seconds = 9; - test_msg.tow = 501867800; - test_msg.year = 2021; - - EXPECT_EQ(send_message(789, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 789); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.day, 9) - << "incorrect value for last_msg_.day, expected 9, is " << last_msg_.day; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.hours, 19) - << "incorrect value for last_msg_.hours, expected 19, is " - << last_msg_.hours; - EXPECT_EQ(last_msg_.minutes, 24) - << "incorrect value for last_msg_.minutes, expected 24, is " - << last_msg_.minutes; - EXPECT_EQ(last_msg_.month, 4) - << "incorrect value for last_msg_.month, expected 4, is " - << last_msg_.month; - EXPECT_EQ(last_msg_.ns, 800000000) - << "incorrect value for last_msg_.ns, expected 800000000, is " - << last_msg_.ns; - EXPECT_EQ(last_msg_.seconds, 9) - << "incorrect value for last_msg_.seconds, expected 9, is " - << last_msg_.seconds; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.year, 2021) - << "incorrect value for last_msg_.year, expected 2021, is " - << last_msg_.year; + EXPECT_EQ(sbp_msg_utc_time_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_utc_time_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_utc_time_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUtcTime, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.day, greater.day); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.hours, greater.hours); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.minutes, greater.minutes); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.month, greater.month); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.ns, greater.ns); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.seconds, greater.seconds); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_t lesser = info.test_msg; + sbp_msg_utc_time_t greater = info.test_msg; + make_lesser_greater(lesser.year, greater.year); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgUtcTime); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_UTC_TIME"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_utc_time_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_utc_time_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.utc_time, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.utc_time, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUtcTime, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTime0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgUtcTime, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgUTCTimeGNSS.cc b/c/test/cpp/auto_check_sbp_navigation_MsgUTCTimeGNSS.cc index 5f9bb6fbdb..b072fa069a 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgUTCTimeGNSS.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgUTCTimeGNSS.cc @@ -16,117 +16,629 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgUTCTimeGNSS0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgUTCTimeGNSS0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgUTCTimeGNSS0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgUTCTimeGNSS0() { + assign(test_msg_.day, 9); + assign(test_msg_.flags, 1); + assign(test_msg_.hours, 19); + assign(test_msg_.minutes, 24); + assign(test_msg_.month, 4); + assign(test_msg_.ns, 800000000); + assign(test_msg_.seconds, 9); + assign(test_msg_.tow, 501867800); + assign(test_msg_.year, 2021); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_time_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_utc_time_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUtcTimeGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_utc_time_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUtcTimeGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->utc_time_gnss, + sizeof(msg->utc_time_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_utc_time_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.utc_time_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUtcTimeGnss); + info.sender_id = 789; + info.preamble = 0x55; + info.crc = 0x21b1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 16; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_utc_time_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_utc_time_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_utc_time_gnss_t &lesser, + const sbp_msg_utc_time_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_utc_time_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_utc_time_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_utc_time_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_utc_time_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUtcTimeGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgUtcTimeGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUtcTimeGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUtcTimeGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_navigation_MsgUTCTimeGNSS0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_utc_time_gnss_t test_msg_{}; + uint8_t encoded_frame_[16 + 8] = { 85, 5, 1, 21, 3, 16, 1, 24, 229, 233, 29, 229, 7, 4, 9, 19, 24, 9, 0, 8, 175, 47, 177, 33, }; + uint8_t encoded_payload_[16] = { + 1, 24, 229, 233, 29, 229, 7, 4, 9, 19, 24, 9, 0, 8, 175, 47, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_utc_time_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgUtcTimeGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_utc_time_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUtcTimeGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + EXPECT_EQ(sbp_msg_utc_time_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + + for (uint8_t i = 0; i < 16; i++) { + EXPECT_EQ(sbp_msg_utc_time_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_utc_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUtcTimeGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_gnss_t msg{}; - sbp_msg_utc_time_gnss_t test_msg{}; - test_msg.day = 9; - test_msg.flags = 1; - test_msg.hours = 19; - test_msg.minutes = 24; - test_msg.month = 4; - test_msg.ns = 800000000; - test_msg.seconds = 9; - test_msg.tow = 501867800; - test_msg.year = 2021; - - EXPECT_EQ(send_message(789, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 789); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.day, 9) - << "incorrect value for last_msg_.day, expected 9, is " << last_msg_.day; - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.hours, 19) - << "incorrect value for last_msg_.hours, expected 19, is " - << last_msg_.hours; - EXPECT_EQ(last_msg_.minutes, 24) - << "incorrect value for last_msg_.minutes, expected 24, is " - << last_msg_.minutes; - EXPECT_EQ(last_msg_.month, 4) - << "incorrect value for last_msg_.month, expected 4, is " - << last_msg_.month; - EXPECT_EQ(last_msg_.ns, 800000000) - << "incorrect value for last_msg_.ns, expected 800000000, is " - << last_msg_.ns; - EXPECT_EQ(last_msg_.seconds, 9) - << "incorrect value for last_msg_.seconds, expected 9, is " - << last_msg_.seconds; - EXPECT_EQ(last_msg_.tow, 501867800) - << "incorrect value for last_msg_.tow, expected 501867800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.year, 2021) - << "incorrect value for last_msg_.year, expected 2021, is " - << last_msg_.year; + EXPECT_EQ(sbp_msg_utc_time_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_utc_time_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_utc_time_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUtcTimeGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.day, greater.day); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.hours, greater.hours); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.minutes, greater.minutes); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.month, greater.month); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.ns, greater.ns); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.seconds, greater.seconds); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_utc_time_gnss_t lesser = info.test_msg; + sbp_msg_utc_time_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.year, greater.year); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUtcTimeGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UTC_TIME_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_utc_time_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_utc_time_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.utc_time_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.utc_time_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[16]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 16); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 16), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_utc_time_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 16); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUtcTimeGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgUTCTimeGNSS0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUtcTimeGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelBody.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelBody.cc index eb7ad89acf..4609fe772e 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelBody.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelBody.cc @@ -16,127 +16,638 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelBody0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelBody0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelBody0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelBody0() { + assign(test_msg_.cov_x_x, 0.0); + assign(test_msg_.cov_x_y, 5.0); + assign(test_msg_.cov_x_z, 7.0); + assign(test_msg_.cov_y_y, 7.0); + assign(test_msg_.cov_y_z, 3.0); + assign(test_msg_.cov_z_z, 2.0); + assign(test_msg_.flags, 8); + assign(test_msg_.n_sats, 3); + assign(test_msg_.tow, 1); + assign(test_msg_.x, 4); + assign(test_msg_.y, 2); + assign(test_msg_.z, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_body_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_body_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelBody, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_body_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelBody); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_body, sizeof(msg->vel_body)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_body_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_body, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelBody); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x9078; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_body_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_body_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_body_t &lesser, + const sbp_msg_vel_body_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_body_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_body_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_body_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_body_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelBody, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelBody, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelBody, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelBody, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelBody0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_body_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { 85, 19, 2, 66, 0, 42, 1, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 160, 64, 0, 0, 224, 64, 0, 0, 224, 64, 0, 0, 64, 64, 0, 0, 0, 64, 3, 8, 120, 144, }; + uint8_t encoded_payload_[42] = { + 1, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 160, 64, 0, 0, 224, 64, 0, 0, 224, 64, 0, 0, 64, 64, 0, 0, 0, 64, 3, 8, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_body_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelBody, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_body_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelBody, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ( + sbp_msg_vel_body_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ(sbp_msg_vel_body_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_body_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_body_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelBody, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_body_t msg{}; + + EXPECT_EQ(sbp_msg_vel_body_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_body_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_body_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_body_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelBody, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_body_t test_msg{}; - test_msg.cov_x_x = 0.0; - test_msg.cov_x_y = 5.0; - test_msg.cov_x_z = 7.0; - test_msg.cov_y_y = 7.0; - test_msg.cov_y_z = 3.0; - test_msg.cov_z_z = 2.0; - test_msg.flags = 8; - test_msg.n_sats = 3; - test_msg.tow = 1; - test_msg.x = 4; - test_msg.y = 2; - test_msg.z = 1; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_x_x * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_x, expected 0.0, is " - << last_msg_.cov_x_x; - EXPECT_LT((last_msg_.cov_x_y * 100 - 5.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_y, expected 5.0, is " - << last_msg_.cov_x_y; - EXPECT_LT((last_msg_.cov_x_z * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_z, expected 7.0, is " - << last_msg_.cov_x_z; - EXPECT_LT((last_msg_.cov_y_y * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_y, expected 7.0, is " - << last_msg_.cov_y_y; - EXPECT_LT((last_msg_.cov_y_z * 100 - 3.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_z, expected 3.0, is " - << last_msg_.cov_y_z; - EXPECT_LT((last_msg_.cov_z_z * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_z_z, expected 2.0, is " - << last_msg_.cov_z_z; - EXPECT_EQ(last_msg_.flags, 8) - << "incorrect value for last_msg_.flags, expected 8, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 3) - << "incorrect value for last_msg_.n_sats, expected 3, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 1) - << "incorrect value for last_msg_.tow, expected 1, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 4) - << "incorrect value for last_msg_.x, expected 4, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 2) - << "incorrect value for last_msg_.y, expected 2, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 1) - << "incorrect value for last_msg_.z, expected 1, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_x, greater.cov_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_y, greater.cov_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_z, greater.cov_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_y, greater.cov_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_z, greater.cov_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.cov_z_z, greater.cov_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_body_t lesser = info.test_msg; + sbp_msg_vel_body_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelBody); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_BODY"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_body_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_body_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_body, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_body, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_body_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelBody, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelBody0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelBody, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelCog.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelCog.cc index 597c8defdd..6d88a461cc 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelCog.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelCog.cc @@ -16,330 +16,1795 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelCog0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelCog0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelCog0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelCog0() { + assign(test_msg_.cog, 1000); + assign(test_msg_.cog_accuracy, 4000); + assign(test_msg_.flags, 62); + assign(test_msg_.sog, 2000); + assign(test_msg_.sog_accuracy, 5000); + assign(test_msg_.tow, 326825520); + assign(test_msg_.v_up, 3000); + assign(test_msg_.v_up_accuracy, 6000); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_cog_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelCog, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelCog); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_cog, sizeof(msg->vel_cog)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_cog_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_cog, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelCog); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xC1D4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 30; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_cog_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_cog_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_cog_t &lesser, + const sbp_msg_vel_cog_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_cog_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_cog_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_cog_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_cog_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_navigation_MsgVelCog0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_cog_t test_msg_{}; + uint8_t encoded_frame_[30 + 8] = { 85, 28, 2, 211, 136, 30, 48, 246, 122, 19, 232, 3, 0, 0, 208, 7, 0, 0, 184, 11, 0, 0, 160, 15, 0, 0, 136, 19, 0, 0, 112, 23, 0, 0, 62, 0, 212, 193, }; + uint8_t encoded_payload_[30] = { + 48, 246, 122, 19, 232, 3, 0, 0, 208, 7, 0, 0, 184, 11, 0, + 0, 160, 15, 0, 0, 136, 19, 0, 0, 112, 23, 0, 0, 62, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_cog_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelCog, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelCog, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + for (uint8_t i = 0; i < 30; i++) { + EXPECT_EQ(sbp_msg_vel_cog_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelCog, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_cog_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_cog_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelCog, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog, greater.cog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog_accuracy, greater.cog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog, greater.sog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog_accuracy, greater.sog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up, greater.v_up); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up_accuracy, greater.v_up_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelCog); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_COG"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - sbp_msg_vel_cog_t test_msg{}; - test_msg.cog = 1000; - test_msg.cog_accuracy = 4000; - test_msg.flags = 62; - test_msg.sog = 2000; - test_msg.sog_accuracy = 5000; - test_msg.tow = 326825520; - test_msg.v_up = 3000; - test_msg.v_up_accuracy = 6000; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cog, 1000) - << "incorrect value for last_msg_.cog, expected 1000, is " - << last_msg_.cog; - EXPECT_EQ(last_msg_.cog_accuracy, 4000) - << "incorrect value for last_msg_.cog_accuracy, expected 4000, is " - << last_msg_.cog_accuracy; - EXPECT_EQ(last_msg_.flags, 62) - << "incorrect value for last_msg_.flags, expected 62, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.sog, 2000) - << "incorrect value for last_msg_.sog, expected 2000, is " - << last_msg_.sog; - EXPECT_EQ(last_msg_.sog_accuracy, 5000) - << "incorrect value for last_msg_.sog_accuracy, expected 5000, is " - << last_msg_.sog_accuracy; - EXPECT_EQ(last_msg_.tow, 326825520) - << "incorrect value for last_msg_.tow, expected 326825520, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_up, 3000) - << "incorrect value for last_msg_.v_up, expected 3000, is " - << last_msg_.v_up; - EXPECT_EQ(last_msg_.v_up_accuracy, 6000) - << "incorrect value for last_msg_.v_up_accuracy, expected 6000, is " - << last_msg_.v_up_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelCog1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + const sbp_msg_vel_cog_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_cog_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_cog, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_cog, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelCog, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelCog, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelCog1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelCog1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelCog1() { + assign(test_msg_.cog, 123); + assign(test_msg_.cog_accuracy, 180000000); + assign(test_msg_.flags, 0); + assign(test_msg_.sog, 456); + assign(test_msg_.sog_accuracy, 100); + assign(test_msg_.tow, 326825520); + assign(test_msg_.v_up, -1000); + assign(test_msg_.v_up_accuracy, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_cog_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelCog, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelCog); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_cog, sizeof(msg->vel_cog)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_cog_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_cog, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelCog); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x725A; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 30; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_cog_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_cog_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_cog_t &lesser, + const sbp_msg_vel_cog_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_cog_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_cog_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_cog_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_cog_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelCog1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_cog_t test_msg_{}; + uint8_t encoded_frame_[30 + 8] = { 85, 28, 2, 211, 136, 30, 48, 246, 122, 19, 123, 0, 0, 0, 200, 1, 0, 0, 24, 252, 255, 255, 0, 149, 186, 10, 100, 0, 0, 0, 100, 0, 0, 0, 0, 0, 90, 114, }; + uint8_t encoded_payload_[30] = { + 48, 246, 122, 19, 123, 0, 0, 0, 200, 1, 0, 0, 24, 252, 255, + 255, 0, 149, 186, 10, 100, 0, 0, 0, 100, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_cog_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelCog, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelCog, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + for (uint8_t i = 0; i < 30; i++) { + EXPECT_EQ(sbp_msg_vel_cog_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelCog, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_vel_cog_t test_msg{}; - test_msg.cog = 123; - test_msg.cog_accuracy = 180000000; - test_msg.flags = 0; - test_msg.sog = 456; - test_msg.sog_accuracy = 100; - test_msg.tow = 326825520; - test_msg.v_up = -1000; - test_msg.v_up_accuracy = 100; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cog, 123) - << "incorrect value for last_msg_.cog, expected 123, is " - << last_msg_.cog; - EXPECT_EQ(last_msg_.cog_accuracy, 180000000) - << "incorrect value for last_msg_.cog_accuracy, expected 180000000, is " - << last_msg_.cog_accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.sog, 456) - << "incorrect value for last_msg_.sog, expected 456, is " - << last_msg_.sog; - EXPECT_EQ(last_msg_.sog_accuracy, 100) - << "incorrect value for last_msg_.sog_accuracy, expected 100, is " - << last_msg_.sog_accuracy; - EXPECT_EQ(last_msg_.tow, 326825520) - << "incorrect value for last_msg_.tow, expected 326825520, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_up, -1000) - << "incorrect value for last_msg_.v_up, expected -1000, is " - << last_msg_.v_up; - EXPECT_EQ(last_msg_.v_up_accuracy, 100) - << "incorrect value for last_msg_.v_up_accuracy, expected 100, is " - << last_msg_.v_up_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelCog2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_cog_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_cog_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelCog, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog, greater.cog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog_accuracy, greater.cog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog, greater.sog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog_accuracy, greater.sog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up, greater.v_up); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up_accuracy, greater.v_up_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelCog); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_COG"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_cog_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_cog_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_cog, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_cog, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelCog, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelCog, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelCog2 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelCog2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelCog2() { + assign(test_msg_.cog, 0); + assign(test_msg_.cog_accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.sog, 0); + assign(test_msg_.sog_accuracy, 0); + assign(test_msg_.tow, 326825520); + assign(test_msg_.v_up, 0); + assign(test_msg_.v_up_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_cog_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelCog, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_cog_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelCog); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_cog, sizeof(msg->vel_cog)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_cog_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_cog, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelCog); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xD22A; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 30; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_cog_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_cog_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_cog_t &lesser, + const sbp_msg_vel_cog_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_cog_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_cog_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_cog_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_cog_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelCog, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelCog, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelCog2, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_cog_t test_msg_{}; + uint8_t encoded_frame_[30 + 8] = { 85, 28, 2, 211, 136, 30, 48, 246, 122, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42, 210, }; + uint8_t encoded_payload_[30] = { + 48, 246, 122, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_cog_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelCog, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelCog, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + EXPECT_EQ( + sbp_msg_vel_cog_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + + for (uint8_t i = 0; i < 30; i++) { + EXPECT_EQ(sbp_msg_vel_cog_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelCog, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + EXPECT_EQ(sbp_msg_vel_cog_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_cog_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_cog_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_vel_cog_t test_msg{}; - test_msg.cog = 0; - test_msg.cog_accuracy = 0; - test_msg.flags = 0; - test_msg.sog = 0; - test_msg.sog_accuracy = 0; - test_msg.tow = 326825520; - test_msg.v_up = 0; - test_msg.v_up_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cog, 0) - << "incorrect value for last_msg_.cog, expected 0, is " << last_msg_.cog; - EXPECT_EQ(last_msg_.cog_accuracy, 0) - << "incorrect value for last_msg_.cog_accuracy, expected 0, is " - << last_msg_.cog_accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.sog, 0) - << "incorrect value for last_msg_.sog, expected 0, is " << last_msg_.sog; - EXPECT_EQ(last_msg_.sog_accuracy, 0) - << "incorrect value for last_msg_.sog_accuracy, expected 0, is " - << last_msg_.sog_accuracy; - EXPECT_EQ(last_msg_.tow, 326825520) - << "incorrect value for last_msg_.tow, expected 326825520, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_up, 0) - << "incorrect value for last_msg_.v_up, expected 0, is " - << last_msg_.v_up; - EXPECT_EQ(last_msg_.v_up_accuracy, 0) - << "incorrect value for last_msg_.v_up_accuracy, expected 0, is " - << last_msg_.v_up_accuracy; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelCog, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog, greater.cog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.cog_accuracy, greater.cog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog, greater.sog); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.sog_accuracy, greater.sog_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up, greater.v_up); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_cog_t lesser = info.test_msg; + sbp_msg_vel_cog_t greater = info.test_msg; + make_lesser_greater(lesser.v_up_accuracy, greater.v_up_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelCog); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_COG"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_cog_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_cog_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_cog, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_cog, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[30]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 30); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 30), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_cog_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 30); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelCog, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelCog2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelCog, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEF.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEF.cc index f174fe5a0f..a4b0c57b39 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEF.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEF.cc @@ -16,511 +16,2954 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelECEF0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelECEF0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelECEF0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelECEF0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 14); + assign(test_msg_.tow, 326825000); + assign(test_msg_.x, -8); + assign(test_msg_.y, -5); + assign(test_msg_.z, 10); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef, sizeof(msg->vel_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x63b5; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_t &lesser, + const sbp_msg_vel_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEF0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 13, 2, 211, 136, 20, 40, 244, 122, 19, 248, 255, 255, 255, 251, 255, 255, 255, 10, 0, 0, 0, 0, 0, 14, 0, 181, 99, }; + uint8_t encoded_payload_[20] = { + 40, 244, 122, 19, 248, 255, 255, 255, 251, 255, + 255, 255, 10, 0, 0, 0, 0, 0, 14, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - sbp_msg_vel_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 14; - test_msg.tow = 326825000; - test_msg.x = -8; - test_msg.y = -5; - test_msg.z = 10; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 14) - << "incorrect value for last_msg_.n_sats, expected 14, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -8) - << "incorrect value for last_msg_.x, expected -8, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -5) - << "incorrect value for last_msg_.y, expected -5, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 10) - << "incorrect value for last_msg_.z, expected 10, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEF1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEF1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelECEF1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelECEF1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326825500); + assign(test_msg_.x, -12); + assign(test_msg_.y, -18); + assign(test_msg_.z, 11); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef, sizeof(msg->vel_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x78d7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_t &lesser, + const sbp_msg_vel_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEF1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_vel_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 13, 2, 211, 136, 20, 28, 246, 122, 19, 244, 255, 255, 255, 238, 255, 255, 255, 11, 0, 0, 0, 0, 0, 15, 0, 215, 120, }; + uint8_t encoded_payload_[20] = { + 28, 246, 122, 19, 244, 255, 255, 255, 238, 255, + 255, 255, 11, 0, 0, 0, 0, 0, 15, 0, + }; +}; - sbp_msg_vel_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326825500; - test_msg.x = -12; - test_msg.y = -18; - test_msg.z = 11; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825500) - << "incorrect value for last_msg_.tow, expected 326825500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -12) - << "incorrect value for last_msg_.x, expected -12, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -18) - << "incorrect value for last_msg_.y, expected -18, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 11) - << "incorrect value for last_msg_.z, expected 11, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEF2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEF2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEF2, Test) { - uint8_t encoded_frame[] = { - 85, 13, 2, 211, 136, 20, 16, 248, 122, 19, 248, 255, 255, 255, - 250, 255, 255, 255, 7, 0, 0, 0, 0, 0, 15, 0, 248, 221, - }; + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_vel_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.x = -8; - test_msg.y = -6; - test_msg.z = 7; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -8) - << "incorrect value for last_msg_.x, expected -8, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -6) - << "incorrect value for last_msg_.y, expected -6, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 7) - << "incorrect value for last_msg_.z, expected 7, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEF3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEF3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEF3, Test) { - uint8_t encoded_frame[] = { - 85, 13, 2, 211, 136, 20, 4, 250, 122, 19, 249, 255, 255, 255, - 239, 255, 255, 255, 16, 0, 0, 0, 0, 0, 15, 0, 1, 167, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_vel_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326826500; - test_msg.x = -7; - test_msg.y = -17; - test_msg.z = 16; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826500) - << "incorrect value for last_msg_.tow, expected 326826500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -7) - << "incorrect value for last_msg_.x, expected -7, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -17) - << "incorrect value for last_msg_.y, expected -17, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 16) - << "incorrect value for last_msg_.z, expected 16, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEF4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEF4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEF4, Test) { - uint8_t encoded_frame[] = { - 85, 13, 2, 211, 136, 20, 248, 251, 122, 19, 247, 255, 255, 255, - 243, 255, 255, 255, 14, 0, 0, 0, 0, 0, 15, 0, 191, 43, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_vel_ecef_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.x = -9; - test_msg.y = -13; - test_msg.z = 14; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -9) - << "incorrect value for last_msg_.x, expected -9, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -13) - << "incorrect value for last_msg_.y, expected -13, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 14) - << "incorrect value for last_msg_.z, expected 14, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_ECEF"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEF2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEF2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.x, -8); + assign(test_msg_.y, -6); + assign(test_msg_.z, 7); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef, sizeof(msg->vel_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xddf8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_t &lesser, + const sbp_msg_vel_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 13, 2, 211, 136, 20, 16, 248, 122, 19, 248, 255, 255, 255, + 250, 255, 255, 255, 7, 0, 0, 0, 0, 0, 15, 0, 248, 221, + }; + uint8_t encoded_payload_[20] = { + 16, 248, 122, 19, 248, 255, 255, 255, 250, 255, + 255, 255, 7, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEF3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEF3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826500); + assign(test_msg_.x, -7); + assign(test_msg_.y, -17); + assign(test_msg_.z, 16); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef, sizeof(msg->vel_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xa701; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_t &lesser, + const sbp_msg_vel_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 13, 2, 211, 136, 20, 4, 250, 122, 19, 249, 255, 255, 255, + 239, 255, 255, 255, 16, 0, 0, 0, 0, 0, 15, 0, 1, 167, + }; + uint8_t encoded_payload_[20] = { + 4, 250, 122, 19, 249, 255, 255, 255, 239, 255, + 255, 255, 16, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEF4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEF4() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.x, -9); + assign(test_msg_.y, -13); + assign(test_msg_.z, 14); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcef, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef, sizeof(msg->vel_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcef); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x2bbf; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_t &lesser, + const sbp_msg_vel_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 13, 2, 211, 136, 20, 248, 251, 122, 19, 247, 255, 255, 255, + 243, 255, 255, 255, 14, 0, 0, 0, 0, 0, 15, 0, 191, 43, + }; + uint8_t encoded_payload_[20] = { + 248, 251, 122, 19, 247, 255, 255, 255, 243, 255, + 255, 255, 14, 0, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelEcef, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_vel_ecef_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_t lesser = info.test_msg; + sbp_msg_vel_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelEcef); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_ECEF"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcef, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEF4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelEcef, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFCov.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFCov.cc index 166bff0173..cd381a4266 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFCov.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFCov.cc @@ -16,127 +16,649 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelECEFCov0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelECEFCov0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelECEFCov0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelECEFCov0() { + assign(test_msg_.cov_x_x, 2.0); + assign(test_msg_.cov_x_y, 2.0); + assign(test_msg_.cov_x_z, 2.0); + assign(test_msg_.cov_y_y, 2.0); + assign(test_msg_.cov_y_z, 1.0); + assign(test_msg_.cov_z_z, 3.0); + assign(test_msg_.flags, 4); + assign(test_msg_.n_sats, 3); + assign(test_msg_.tow, 2); + assign(test_msg_.x, 0); + assign(test_msg_.y, 0); + assign(test_msg_.z, 6); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_cov_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_cov_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefCov, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_cov_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefCov); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_cov, + sizeof(msg->vel_ecef_cov)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_cov_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_cov, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefCov); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xfe5b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_cov_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_cov_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_cov_t &lesser, + const sbp_msg_vel_ecef_cov_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cov_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cov_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cov_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cov_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefCov, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefCov, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefCov, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefCov, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFCov0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_cov_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { 85, 21, 2, 66, 0, 42, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 128, 63, 0, 0, 64, 64, 3, 4, 91, 254, }; + uint8_t encoded_payload_[42] = { + 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 64, 0, + 0, 0, 64, 0, 0, 0, 64, 0, 0, 0, 64, 0, 0, 128, 63, 0, 0, 64, 64, 3, 4, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_cov_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefCov, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefCov, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_cov_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefCov, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ecef_cov_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_cov_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefCov, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ecef_cov_t test_msg{}; - test_msg.cov_x_x = 2.0; - test_msg.cov_x_y = 2.0; - test_msg.cov_x_z = 2.0; - test_msg.cov_y_y = 2.0; - test_msg.cov_y_z = 1.0; - test_msg.cov_z_z = 3.0; - test_msg.flags = 4; - test_msg.n_sats = 3; - test_msg.tow = 2; - test_msg.x = 0; - test_msg.y = 0; - test_msg.z = 6; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_x_x * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_x, expected 2.0, is " - << last_msg_.cov_x_x; - EXPECT_LT((last_msg_.cov_x_y * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_y, expected 2.0, is " - << last_msg_.cov_x_y; - EXPECT_LT((last_msg_.cov_x_z * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_z, expected 2.0, is " - << last_msg_.cov_x_z; - EXPECT_LT((last_msg_.cov_y_y * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_y, expected 2.0, is " - << last_msg_.cov_y_y; - EXPECT_LT((last_msg_.cov_y_z * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_z, expected 1.0, is " - << last_msg_.cov_y_z; - EXPECT_LT((last_msg_.cov_z_z * 100 - 3.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_z_z, expected 3.0, is " - << last_msg_.cov_z_z; - EXPECT_EQ(last_msg_.flags, 4) - << "incorrect value for last_msg_.flags, expected 4, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 3) - << "incorrect value for last_msg_.n_sats, expected 3, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2) - << "incorrect value for last_msg_.tow, expected 2, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 0) - << "incorrect value for last_msg_.x, expected 0, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 0) - << "incorrect value for last_msg_.y, expected 0, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 6) - << "incorrect value for last_msg_.z, expected 6, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_x, greater.cov_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_y, greater.cov_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_z, greater.cov_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_y, greater.cov_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_z, greater.cov_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_z_z, greater.cov_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefCov); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_COV"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_cov_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_cov_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_cov, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef_cov, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefCov, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFCov0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefCov, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFDepA.cc index c12ce5ab91..7cbb4f25de 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelECEFDepA.cc @@ -16,1117 +16,6667 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelECEFDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelECEFDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelECEFDepA0() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.x, 3034); + assign(test_msg_.y, -2682); + assign(test_msg_.z, -861); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xec50; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 4, 2, 246, 215, 20, 20, 46, 39, 0, 218, 11, 0, 0, 134, 245, 255, 255, 163, 252, 255, 255, 0, 0, 9, 0, 80, 236, }; + uint8_t encoded_payload_[20] = { + 20, 46, 39, 0, 218, 11, 0, 0, 134, 245, + 255, 255, 163, 252, 255, 255, 0, 0, 9, 0, + }; +}; - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.x = 3034; - test_msg.y = -2682; - test_msg.z = -861; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 3034) - << "incorrect value for last_msg_.x, expected 3034, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -2682) - << "incorrect value for last_msg_.y, expected -2682, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -861) - << "incorrect value for last_msg_.z, expected -861, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 246, 215, 20, 120, 46, 39, 0, 68, 11, 0, 0, - 24, 246, 255, 255, 220, 252, 255, 255, 0, 0, 9, 0, 248, 138, - }; + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.x = 2884; - test_msg.y = -2536; - test_msg.z = -804; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 2884) - << "incorrect value for last_msg_.x, expected 2884, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -2536) - << "incorrect value for last_msg_.y, expected -2536, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -804) - << "incorrect value for last_msg_.z, expected -804, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 246, 215, 20, 220, 46, 39, 0, 21, 11, 0, 0, - 77, 246, 255, 255, 247, 252, 255, 255, 0, 0, 9, 0, 25, 174, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.x = 2837; - test_msg.y = -2483; - test_msg.z = -777; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 2837) - << "incorrect value for last_msg_.x, expected 2837, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -2483) - << "incorrect value for last_msg_.y, expected -2483, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -777) - << "incorrect value for last_msg_.z, expected -777, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 246, 215, 20, 64, 47, 39, 0, 121, 11, 0, 0, - 2, 246, 255, 255, 234, 252, 255, 255, 0, 0, 9, 0, 195, 228, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2568000; - test_msg.x = 2937; - test_msg.y = -2558; - test_msg.z = -790; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568000) - << "incorrect value for last_msg_.tow, expected 2568000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 2937) - << "incorrect value for last_msg_.x, expected 2937, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -2558) - << "incorrect value for last_msg_.y, expected -2558, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -790) - << "incorrect value for last_msg_.z, expected -790, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 246, 215, 20, 164, 47, 39, 0, 31, 11, 0, 0, - 93, 246, 255, 255, 16, 253, 255, 255, 0, 0, 9, 0, 219, 164, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 9; - test_msg.tow = 2568100; - test_msg.x = 2847; - test_msg.y = -2467; - test_msg.z = -752; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568100) - << "incorrect value for last_msg_.tow, expected 2568100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 2847) - << "incorrect value for last_msg_.x, expected 2847, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -2467) - << "incorrect value for last_msg_.y, expected -2467, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -752) - << "incorrect value for last_msg_.z, expected -752, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 212, 157, 67, 24, 24, 0, 0, 0, - 245, 255, 255, 255, 219, 255, 255, 255, 0, 0, 8, 0, 68, 255, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084500; - test_msg.x = 24; - test_msg.y = -11; - test_msg.z = -37; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 24) - << "incorrect value for last_msg_.x, expected 24, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -11) - << "incorrect value for last_msg_.y, expected -11, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -37) - << "incorrect value for last_msg_.z, expected -37, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelECEFDepA1() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.x, 2884); + assign(test_msg_.y, -2536); + assign(test_msg_.z, -804); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 56, 158, 67, 24, 4, 0, 0, 0, - 234, 255, 255, 255, 18, 0, 0, 0, 0, 0, 8, 0, 214, 136, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084600; - test_msg.x = 4; - test_msg.y = -22; - test_msg.z = 18; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084600) - << "incorrect value for last_msg_.tow, expected 407084600, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 4) - << "incorrect value for last_msg_.x, expected 4, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -22) - << "incorrect value for last_msg_.y, expected -22, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 18) - << "incorrect value for last_msg_.z, expected 18, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 156, 158, 67, 24, 230, 255, 255, 255, - 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 122, 159, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084700; - test_msg.x = -26; - test_msg.y = 4; - test_msg.z = 1; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084700) - << "incorrect value for last_msg_.tow, expected 407084700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -26) - << "incorrect value for last_msg_.x, expected -26, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 4) - << "incorrect value for last_msg_.y, expected 4, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 1) - << "incorrect value for last_msg_.z, expected 1, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 0, 159, 67, 24, 247, 255, 255, 255, - 237, 255, 255, 255, 28, 0, 0, 0, 0, 0, 8, 0, 232, 146, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084800; - test_msg.x = -9; - test_msg.y = -19; - test_msg.z = 28; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084800) - << "incorrect value for last_msg_.tow, expected 407084800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -9) - << "incorrect value for last_msg_.x, expected -9, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -19) - << "incorrect value for last_msg_.y, expected -19, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 28) - << "incorrect value for last_msg_.z, expected 28, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 100, 159, 67, 24, 255, 255, 255, 255, - 2, 0, 0, 0, 245, 255, 255, 255, 0, 0, 8, 0, 171, 238, + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 8; - test_msg.tow = 407084900; - test_msg.x = -1; - test_msg.y = 2; - test_msg.z = -11; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084900) - << "incorrect value for last_msg_.tow, expected 407084900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -1) - << "incorrect value for last_msg_.x, expected -1, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 2) - << "incorrect value for last_msg_.y, expected 2, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, -11) - << "incorrect value for last_msg_.z, expected -11, is " << last_msg_.z; -} -class Test_auto_check_sbp_navigation_MsgVelECEFDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelECEFDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8af8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgVelECEFDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 4, 2, 195, 4, 20, 46, 162, 68, 24, 207, 255, 255, 255, - 185, 255, 255, 255, 65, 0, 0, 0, 0, 0, 5, 0, 82, 154, + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 246, 215, 20, 120, 46, 39, 0, 68, 11, 0, 0, + 24, 246, 255, 255, 220, 252, 255, 255, 0, 0, 9, 0, 248, 138, + }; + uint8_t encoded_payload_[20] = { + 120, 46, 39, 0, 68, 11, 0, 0, 24, 246, + 255, 255, 220, 252, 255, 255, 0, 0, 9, 0, }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - sbp_msg_vel_ecef_dep_a_t test_msg{}; - test_msg.accuracy = 0; - test_msg.flags = 0; - test_msg.n_sats = 5; - test_msg.tow = 407151150; - test_msg.x = -49; - test_msg.y = -71; - test_msg.z = 65; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 0) - << "incorrect value for last_msg_.accuracy, expected 0, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 5) - << "incorrect value for last_msg_.n_sats, expected 5, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407151150) - << "incorrect value for last_msg_.tow, expected 407151150, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -49) - << "incorrect value for last_msg_.x, expected -49, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, -71) - << "incorrect value for last_msg_.y, expected -71, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 65) - << "incorrect value for last_msg_.z, expected 65, is " << last_msg_.z; + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA2() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.x, 2837); + assign(test_msg_.y, -2483); + assign(test_msg_.z, -777); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xae19; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 246, 215, 20, 220, 46, 39, 0, 21, 11, 0, 0, + 77, 246, 255, 255, 247, 252, 255, 255, 0, 0, 9, 0, 25, 174, + }; + uint8_t encoded_payload_[20] = { + 220, 46, 39, 0, 21, 11, 0, 0, 77, 246, + 255, 255, 247, 252, 255, 255, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA3() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568000); + assign(test_msg_.x, 2937); + assign(test_msg_.y, -2558); + assign(test_msg_.z, -790); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xe4c3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 246, 215, 20, 64, 47, 39, 0, 121, 11, 0, 0, + 2, 246, 255, 255, 234, 252, 255, 255, 0, 0, 9, 0, 195, 228, + }; + uint8_t encoded_payload_[20] = { + 64, 47, 39, 0, 121, 11, 0, 0, 2, 246, + 255, 255, 234, 252, 255, 255, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA4() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568100); + assign(test_msg_.x, 2847); + assign(test_msg_.y, -2467); + assign(test_msg_.z, -752); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xa4db; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 246, 215, 20, 164, 47, 39, 0, 31, 11, 0, 0, + 93, 246, 255, 255, 16, 253, 255, 255, 0, 0, 9, 0, 219, 164, + }; + uint8_t encoded_payload_[20] = { + 164, 47, 39, 0, 31, 11, 0, 0, 93, 246, + 255, 255, 16, 253, 255, 255, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA5() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084500); + assign(test_msg_.x, 24); + assign(test_msg_.y, -11); + assign(test_msg_.z, -37); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xff44; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 212, 157, 67, 24, 24, 0, 0, 0, + 245, 255, 255, 255, 219, 255, 255, 255, 0, 0, 8, 0, 68, 255, + }; + uint8_t encoded_payload_[20] = { + 212, 157, 67, 24, 24, 0, 0, 0, 245, 255, + 255, 255, 219, 255, 255, 255, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA6() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084600); + assign(test_msg_.x, 4); + assign(test_msg_.y, -22); + assign(test_msg_.z, 18); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x88d6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 56, 158, 67, 24, 4, 0, 0, 0, + 234, 255, 255, 255, 18, 0, 0, 0, 0, 0, 8, 0, 214, 136, + }; + uint8_t encoded_payload_[20] = { + 56, 158, 67, 24, 4, 0, 0, 0, 234, 255, 255, 255, 18, 0, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA7() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084700); + assign(test_msg_.x, -26); + assign(test_msg_.y, 4); + assign(test_msg_.z, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x9f7a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 156, 158, 67, 24, 230, 255, 255, 255, + 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, 122, 159, + }; + uint8_t encoded_payload_[20] = { + 156, 158, 67, 24, 230, 255, 255, 255, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA8() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084800); + assign(test_msg_.x, -9); + assign(test_msg_.y, -19); + assign(test_msg_.z, 28); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x92e8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 0, 159, 67, 24, 247, 255, 255, 255, + 237, 255, 255, 255, 28, 0, 0, 0, 0, 0, 8, 0, 232, 146, + }; + uint8_t encoded_payload_[20] = { + 0, 159, 67, 24, 247, 255, 255, 255, 237, 255, + 255, 255, 28, 0, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA9 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA9() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084900); + assign(test_msg_.x, -1); + assign(test_msg_.y, 2); + assign(test_msg_.z, -11); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xeeab; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 100, 159, 67, 24, 255, 255, 255, 255, + 2, 0, 0, 0, 245, 255, 255, 255, 0, 0, 8, 0, 171, 238, + }; + uint8_t encoded_payload_[20] = { + 100, 159, 67, 24, 255, 255, 255, 255, 2, 0, + 0, 0, 245, 255, 255, 255, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelECEFDepA10 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelECEFDepA10() { + assign(test_msg_.accuracy, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.n_sats, 5); + assign(test_msg_.tow, 407151150); + assign(test_msg_.x, -49); + assign(test_msg_.y, -71); + assign(test_msg_.z, 65); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_dep_a, + sizeof(msg->vel_ecef_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x9a52; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ecef_dep_a_t &lesser, + const sbp_msg_vel_ecef_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 4, 2, 195, 4, 20, 46, 162, 68, 24, 207, 255, 255, 255, + 185, 255, 255, 255, 65, 0, 0, 0, 0, 0, 5, 0, 82, 154, + }; + uint8_t encoded_payload_[20] = { + 46, 162, 68, 24, 207, 255, 255, 255, 185, 255, + 255, 255, 65, 0, 0, 0, 0, 0, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ecef_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelECEFDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefCovGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefCovGnss.cc index 2ae9141b0b..b3126b0fae 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefCovGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefCovGnss.cc @@ -16,130 +16,663 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelEcefCovGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelEcefCovGnss0 + : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelEcefCovGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelEcefCovGnss0() { + assign(test_msg_.cov_x_x, 0.0024547684006392956); + assign(test_msg_.cov_x_y, 0.0021795108914375305); + assign(test_msg_.cov_x_z, -0.0016828652005642653); + assign(test_msg_.cov_y_y, 0.004218944814056158); + assign(test_msg_.cov_y_z, -0.0024961293675005436); + assign(test_msg_.cov_z_z, 0.0037804271560162306); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 21); + assign(test_msg_.tow, 501868000); + assign(test_msg_.x, -3); + assign(test_msg_.y, 1); + assign(test_msg_.z, 4); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_cov_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_cov_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefCovGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_cov_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefCovGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_cov_gnss, + sizeof(msg->vel_ecef_cov_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_cov_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_cov_gnss, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefCovGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0xe616; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_cov_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_cov_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_cov_gnss_t &lesser, + const sbp_msg_vel_ecef_cov_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_cov_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_cov_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefCovGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelEcefCovGnss, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelEcefCovGnss, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelEcefCovGnss, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelEcefCovGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_cov_gnss_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { 85, 53, 2, 0, 16, 42, 224, 229, 233, 29, 253, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 46, 224, 32, 59, 32, 214, 14, 59, 150, 147, 220, 186, 19, 63, 138, 59, 26, 150, 35, 187, 11, 193, 119, 59, 21, 2, 22, 230, }; + uint8_t encoded_payload_[42] = { + 224, 229, 233, 29, 253, 255, 255, 255, 1, 0, 0, 0, 4, 0, + 0, 0, 46, 224, 32, 59, 32, 214, 14, 59, 150, 147, 220, 186, + 19, 63, 138, 59, 26, 150, 35, 187, 11, 193, 119, 59, 21, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgVelEcefCovGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefCovGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ( + sbp_msg_vel_ecef_cov_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefCovGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_cov_gnss_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefCovGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ecef_cov_gnss_t test_msg{}; - test_msg.cov_x_x = 0.0024547684006392956; - test_msg.cov_x_y = 0.0021795108914375305; - test_msg.cov_x_z = -0.0016828652005642653; - test_msg.cov_y_y = 0.004218944814056158; - test_msg.cov_y_z = -0.0024961293675005436; - test_msg.cov_z_z = 0.0037804271560162306; - test_msg.flags = 2; - test_msg.n_sats = 21; - test_msg.tow = 501868000; - test_msg.x = -3; - test_msg.y = 1; - test_msg.z = 4; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_x_x * 100 - 0.00245476840064 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_x, expected 0.00245476840064, is " - << last_msg_.cov_x_x; - EXPECT_LT((last_msg_.cov_x_y * 100 - 0.00217951089144 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_y, expected 0.00217951089144, is " - << last_msg_.cov_x_y; - EXPECT_LT((last_msg_.cov_x_z * 100 - -0.00168286520056 * 100), 0.05) - << "incorrect value for last_msg_.cov_x_z, expected -0.00168286520056, " - "is " - << last_msg_.cov_x_z; - EXPECT_LT((last_msg_.cov_y_y * 100 - 0.00421894481406 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_y, expected 0.00421894481406, is " - << last_msg_.cov_y_y; - EXPECT_LT((last_msg_.cov_y_z * 100 - -0.0024961293675 * 100), 0.05) - << "incorrect value for last_msg_.cov_y_z, expected -0.0024961293675, is " - << last_msg_.cov_y_z; - EXPECT_LT((last_msg_.cov_z_z * 100 - 0.00378042715602 * 100), 0.05) - << "incorrect value for last_msg_.cov_z_z, expected 0.00378042715602, is " - << last_msg_.cov_z_z; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 21) - << "incorrect value for last_msg_.n_sats, expected 21, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501868000) - << "incorrect value for last_msg_.tow, expected 501868000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -3) - << "incorrect value for last_msg_.x, expected -3, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1) - << "incorrect value for last_msg_.y, expected 1, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 4) - << "incorrect value for last_msg_.z, expected 4, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_x, greater.cov_x_x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_y, greater.cov_x_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_x_z, greater.cov_x_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_y, greater.cov_y_y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_y_z, greater.cov_y_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_z_z, greater.cov_z_z); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefCovGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_COV_GNSS"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_cov_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_cov_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.vel_ecef_cov_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ecef_cov_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefCovGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefCovGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefCovGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefGnss.cc index 5d38db2857..6c4fb11a1d 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelEcefGnss.cc @@ -16,107 +16,616 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelEcefGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelEcefGnss0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelEcefGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelEcefGnss0() { + assign(test_msg_.accuracy, 89); + assign(test_msg_.flags, 2); + assign(test_msg_.n_sats, 21); + assign(test_msg_.tow, 501868000); + assign(test_msg_.x, -3); + assign(test_msg_.y, 1); + assign(test_msg_.z, 4); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ecef_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelEcefGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ecef_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelEcefGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ecef_gnss, + sizeof(msg->vel_ecef_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ecef_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ecef_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelEcefGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0x10cd; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ecef_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ecef_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ecef_gnss_t &lesser, + const sbp_msg_vel_ecef_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ecef_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ecef_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ecef_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelEcefGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelEcefGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelEcefGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelEcefGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ecef_gnss_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 45, 2, 0, 16, 20, 224, 229, 233, 29, 253, 255, 255, 255, 1, 0, 0, 0, 4, 0, 0, 0, 89, 0, 21, 2, 205, 16, }; + uint8_t encoded_payload_[20] = { + 224, 229, 233, 29, 253, 255, 255, 255, 1, 0, + 0, 0, 4, 0, 0, 0, 89, 0, 21, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ecef_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelEcefGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelEcefGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; - sbp_msg_vel_ecef_gnss_t test_msg{}; - test_msg.accuracy = 89; - test_msg.flags = 2; - test_msg.n_sats = 21; - test_msg.tow = 501868000; - test_msg.x = -3; - test_msg.y = 1; - test_msg.z = 4; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.accuracy, 89) - << "incorrect value for last_msg_.accuracy, expected 89, is " - << last_msg_.accuracy; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_sats, 21) - << "incorrect value for last_msg_.n_sats, expected 21, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501868000) - << "incorrect value for last_msg_.tow, expected 501868000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.x, -3) - << "incorrect value for last_msg_.x, expected -3, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 1) - << "incorrect value for last_msg_.y, expected 1, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 4) - << "incorrect value for last_msg_.z, expected 4, is " << last_msg_.z; + EXPECT_EQ(sbp_msg_vel_ecef_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); } +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_vel_ecef_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelEcefGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ecef_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelEcefGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.accuracy, greater.accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ecef_gnss_t lesser = info.test_msg; + sbp_msg_vel_ecef_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelEcefGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_ECEF_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ecef_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ecef_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ecef_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ecef_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ecef_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelEcefGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelEcefGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelEcefGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelNED.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelNED.cc index 9d6706314e..d3b379d853 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelNED.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelNED.cc @@ -16,531 +16,2979 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelNED0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelNED0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNED0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNED0() { + assign(test_msg_.d, -13); + assign(test_msg_.e, -4); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 3); + assign(test_msg_.n_sats, 14); + assign(test_msg_.tow, 326825000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNed, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned, sizeof(msg->vel_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xd156; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_t &lesser, + const sbp_msg_vel_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNED0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 14, 2, 211, 136, 22, 40, 244, 122, 19, 3, 0, 0, 0, 252, 255, 255, 255, 243, 255, 255, 255, 0, 0, 0, 0, 14, 0, 86, 209, }; + uint8_t encoded_payload_[22] = { + 40, 244, 122, 19, 3, 0, 0, 0, 252, 255, 255, + 255, 243, 255, 255, 255, 0, 0, 0, 0, 14, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelNed, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNed); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_vel_ned_t test_msg{}; - test_msg.d = -13; - test_msg.e = -4; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 3; - test_msg.n_sats = 14; - test_msg.tow = 326825000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -13) - << "incorrect value for last_msg_.d, expected -13, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -4) - << "incorrect value for last_msg_.e, expected -4, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 3) - << "incorrect value for last_msg_.n, expected 3, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 14) - << "incorrect value for last_msg_.n_sats, expected 14, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825000) - << "incorrect value for last_msg_.tow, expected 326825000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNED1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNed, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelNed, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNED1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNED1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNED1() { + assign(test_msg_.d, -24); + assign(test_msg_.e, -1); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -4); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326825500); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNed, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned, sizeof(msg->vel_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xe410; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_t &lesser, + const sbp_msg_vel_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNED1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 14, 2, 211, 136, 22, 28, 246, 122, 19, 252, 255, 255, 255, 255, 255, 255, 255, 232, 255, 255, 255, 0, 0, 0, 0, 15, 0, 16, 228, }; + uint8_t encoded_payload_[22] = { + 28, 246, 122, 19, 252, 255, 255, 255, 255, 255, 255, + 255, 232, 255, 255, 255, 0, 0, 0, 0, 15, 0, + }; +}; - sbp_msg_vel_ned_t test_msg{}; - test_msg.d = -24; - test_msg.e = -1; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -4; - test_msg.n_sats = 15; - test_msg.tow = 326825500; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -24) - << "incorrect value for last_msg_.d, expected -24, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -1) - << "incorrect value for last_msg_.e, expected -1, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -4) - << "incorrect value for last_msg_.n, expected -4, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326825500) - << "incorrect value for last_msg_.tow, expected 326825500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNED2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNED2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelNed, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgVelNED2, Test) { - uint8_t encoded_frame[] = { - 85, 14, 2, 211, 136, 22, 16, 248, 122, 19, 0, 0, 0, 0, 253, - 255, 255, 255, 244, 255, 255, 255, 0, 0, 0, 0, 15, 0, 11, 164, - }; + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_vel_ned_t test_msg{}; - test_msg.d = -12; - test_msg.e = -3; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 0; - test_msg.n_sats = 15; - test_msg.tow = 326826000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -12) - << "incorrect value for last_msg_.d, expected -12, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -3) - << "incorrect value for last_msg_.e, expected -3, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 0) - << "incorrect value for last_msg_.n, expected 0, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826000) - << "incorrect value for last_msg_.tow, expected 326826000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNED3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNED3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgVelNED3, Test) { - uint8_t encoded_frame[] = { - 85, 14, 2, 211, 136, 22, 4, 250, 122, 19, 2, 0, 0, 0, 3, - 0, 0, 0, 232, 255, 255, 255, 0, 0, 0, 0, 15, 0, 152, 208, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_vel_ned_t test_msg{}; - test_msg.d = -24; - test_msg.e = 3; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 2; - test_msg.n_sats = 15; - test_msg.tow = 326826500; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -24) - << "incorrect value for last_msg_.d, expected -24, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3) - << "incorrect value for last_msg_.e, expected 3, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 2) - << "incorrect value for last_msg_.n, expected 2, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326826500) - << "incorrect value for last_msg_.tow, expected 326826500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNED4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNED4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelNED4, Test) { - uint8_t encoded_frame[] = { - 85, 14, 2, 211, 136, 22, 248, 251, 122, 19, 1, 0, 0, 0, 0, - 0, 0, 0, 235, 255, 255, 255, 0, 0, 0, 0, 15, 0, 182, 120, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} - sbp_msg_vel_ned_t test_msg{}; - test_msg.d = -21; - test_msg.e = 0; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 1; - test_msg.n_sats = 15; - test_msg.tow = 326827000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -21) - << "incorrect value for last_msg_.d, expected -21, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 0) - << "incorrect value for last_msg_.e, expected 0, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 1) - << "incorrect value for last_msg_.n, expected 1, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 15) - << "incorrect value for last_msg_.n_sats, expected 15, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 326827000) - << "incorrect value for last_msg_.tow, expected 326827000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNed); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_NED"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNed, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelNed, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNED2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNED2() { + assign(test_msg_.d, -12); + assign(test_msg_.e, -3); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 0); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNed, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned, sizeof(msg->vel_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xa40b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_t &lesser, + const sbp_msg_vel_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 14, 2, 211, 136, 22, 16, 248, 122, 19, 0, 0, 0, 0, 253, + 255, 255, 255, 244, 255, 255, 255, 0, 0, 0, 0, 15, 0, 11, 164, + }; + uint8_t encoded_payload_[22] = { + 16, 248, 122, 19, 0, 0, 0, 0, 253, 255, 255, + 255, 244, 255, 255, 255, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelNed, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNed); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNed, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelNed, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNED3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNED3() { + assign(test_msg_.d, -24); + assign(test_msg_.e, 3); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 2); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326826500); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNed, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned, sizeof(msg->vel_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xd098; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_t &lesser, + const sbp_msg_vel_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 14, 2, 211, 136, 22, 4, 250, 122, 19, 2, 0, 0, 0, 3, + 0, 0, 0, 232, 255, 255, 255, 0, 0, 0, 0, 15, 0, 152, 208, + }; + uint8_t encoded_payload_[22] = { + 4, 250, 122, 19, 2, 0, 0, 0, 3, 0, 0, + 0, 232, 255, 255, 255, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelNed, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNed); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNed, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelNed, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNED4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNED4() { + assign(test_msg_.d, -21); + assign(test_msg_.e, 0); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 1); + assign(test_msg_.n_sats, 15); + assign(test_msg_.tow, 326827000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNed, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNed); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned, sizeof(msg->vel_ned)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNed); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x78b6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_t &lesser, + const sbp_msg_vel_ned_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgVelNed, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgVelNed, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 14, 2, 211, 136, 22, 248, 251, 122, 19, 1, 0, 0, 0, 0, + 0, 0, 0, 235, 255, 255, 255, 0, 0, 0, 0, 15, 0, 182, 120, + }; + uint8_t encoded_payload_[22] = { + 248, 251, 122, 19, 1, 0, 0, 0, 0, 0, 0, + 0, 235, 255, 255, 255, 0, 0, 0, 0, 15, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNed, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgVelNed, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ( + sbp_msg_vel_ned_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNed, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNed, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_t lesser = info.test_msg; + sbp_msg_vel_ned_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNed); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_VEL_NED"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNed, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNED4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgVelNed, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDCOV.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDCOV.cc index 56d6ca0d05..2d6f35e54a 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDCOV.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDCOV.cc @@ -16,128 +16,645 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelNEDCOV0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelNEDCOV0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNEDCOV0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNEDCOV0() { + assign(test_msg_.cov_d_d, 1.0); + assign(test_msg_.cov_e_d, 1.0); + assign(test_msg_.cov_e_e, 1.0); + assign(test_msg_.cov_n_d, 1.0); + assign(test_msg_.cov_n_e, 1.0); + assign(test_msg_.cov_n_n, 1.0); + assign(test_msg_.d, 1); + assign(test_msg_.e, 1); + assign(test_msg_.flags, 0); + assign(test_msg_.n, 1); + assign(test_msg_.n_sats, 10); + assign(test_msg_.tow, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_cov_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_cov_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedCov, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_cov_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedCov); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_cov, sizeof(msg->vel_ned_cov)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_cov_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_cov, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedCov); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xCD58; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_cov_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_cov_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_cov_t &lesser, + const sbp_msg_vel_ned_cov_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cov_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cov_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cov_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cov_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedCov, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedCov, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedCov, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedCov, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDCOV0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_cov_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { 85, 18, 2, 66, 0, 42, 100, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 10, 0, 88, 205, }; + uint8_t encoded_payload_[42] = { + 100, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, + 0, 0, 128, 63, 0, 0, 128, 63, 0, 0, 128, 63, 10, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_cov_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedCov, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_cov_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedCov, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ( + sbp_msg_vel_ned_cov_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ(sbp_msg_vel_ned_cov_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_cov_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedCov, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_cov_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_cov_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_cov_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedCov, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ned_cov_t test_msg{}; - test_msg.cov_d_d = 1.0; - test_msg.cov_e_d = 1.0; - test_msg.cov_e_e = 1.0; - test_msg.cov_n_d = 1.0; - test_msg.cov_n_e = 1.0; - test_msg.cov_n_n = 1.0; - test_msg.d = 1; - test_msg.e = 1; - test_msg.flags = 0; - test_msg.n = 1; - test_msg.n_sats = 10; - test_msg.tow = 100; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_d_d * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_d_d, expected 1.0, is " - << last_msg_.cov_d_d; - EXPECT_LT((last_msg_.cov_e_d * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_d, expected 1.0, is " - << last_msg_.cov_e_d; - EXPECT_LT((last_msg_.cov_e_e * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_e, expected 1.0, is " - << last_msg_.cov_e_e; - EXPECT_LT((last_msg_.cov_n_d * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_d, expected 1.0, is " - << last_msg_.cov_n_d; - EXPECT_LT((last_msg_.cov_n_e * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_e, expected 1.0, is " - << last_msg_.cov_n_e; - EXPECT_LT((last_msg_.cov_n_n * 100 - 1.0 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_n, expected 1.0, is " - << last_msg_.cov_n_n; - EXPECT_EQ(last_msg_.d, 1) - << "incorrect value for last_msg_.d, expected 1, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 1) - << "incorrect value for last_msg_.e, expected 1, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n, 1) - << "incorrect value for last_msg_.n, expected 1, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 10) - << "incorrect value for last_msg_.n_sats, expected 10, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 100) - << "incorrect value for last_msg_.tow, expected 100, is " - << last_msg_.tow; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_d_d, greater.cov_d_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_d, greater.cov_e_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_e, greater.cov_e_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_d, greater.cov_n_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_e, greater.cov_n_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_n, greater.cov_n_n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgVelNedCov); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_COV"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_cov_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_cov_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_cov, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_cov, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedCov, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDCOV0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedCov, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDDepA.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDDepA.cc index 50b05b8aa4..2b01af9800 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDDepA.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelNEDDepA.cc @@ -16,1161 +16,6702 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelNEDDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelNEDDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNEDDepA0() { + assign(test_msg_.d, 0); + assign(test_msg_.e, 3996); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -1082); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x5ca1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 5, 2, 246, 215, 22, 20, 46, 39, 0, 198, 251, 255, 255, 156, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 161, 92, }; + uint8_t encoded_payload_[22] = { + 20, 46, 39, 0, 198, 251, 255, 255, 156, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + }; +}; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = 3996; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -1082; - test_msg.n_sats = 9; - test_msg.tow = 2567700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3996) - << "incorrect value for last_msg_.e, expected 3996, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -1082) - << "incorrect value for last_msg_.n, expected -1082, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567700) - << "incorrect value for last_msg_.tow, expected 2567700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 246, 215, 22, 120, 46, 39, 0, 14, 252, 255, 255, 207, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 125, 160, - }; + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = 3791; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -1010; - test_msg.n_sats = 9; - test_msg.tow = 2567800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3791) - << "incorrect value for last_msg_.e, expected 3791, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -1010) - << "incorrect value for last_msg_.n, expected -1010, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567800) - << "incorrect value for last_msg_.tow, expected 2567800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 246, 215, 22, 220, 46, 39, 0, 48, 252, 255, 255, 140, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 179, 135, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = 3724; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -976; - test_msg.n_sats = 9; - test_msg.tow = 2567900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3724) - << "incorrect value for last_msg_.e, expected 3724, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -976) - << "incorrect value for last_msg_.n, expected -976, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2567900) - << "incorrect value for last_msg_.tow, expected 2567900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 246, 215, 22, 64, 47, 39, 0, 32, 252, 255, 255, 8, - 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 51, 177, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = 3848; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -992; - test_msg.n_sats = 9; - test_msg.tow = 2568000; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3848) - << "incorrect value for last_msg_.e, expected 3848, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -992) - << "incorrect value for last_msg_.n, expected -992, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568000) - << "incorrect value for last_msg_.tow, expected 2568000, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 246, 215, 22, 164, 47, 39, 0, 80, 252, 255, 255, 140, - 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 23, 0, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 0; - test_msg.e = 3724; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -944; - test_msg.n_sats = 9; - test_msg.tow = 2568100; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 0) - << "incorrect value for last_msg_.d, expected 0, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 3724) - << "incorrect value for last_msg_.e, expected 3724, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -944) - << "incorrect value for last_msg_.n, expected -944, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 9) - << "incorrect value for last_msg_.n_sats, expected 9, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 2568100) - << "incorrect value for last_msg_.tow, expected 2568100, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 212, 157, 67, 24, 229, 255, 255, 255, 26, - 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 8, 0, 132, 25, - }; +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 25; - test_msg.e = 26; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -27; - test_msg.n_sats = 8; - test_msg.tow = 407084500; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 25) - << "incorrect value for last_msg_.d, expected 25, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 26) - << "incorrect value for last_msg_.e, expected 26, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -27) - << "incorrect value for last_msg_.n, expected -27, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084500) - << "incorrect value for last_msg_.tow, expected 407084500, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +class Testauto_check_sbp_navigation_MsgVelNEDDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNEDDepA1() { + assign(test_msg_.d, 0); + assign(test_msg_.e, 3791); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -1010); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567800); + assign(test_msg_.v_accuracy, 0); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA6, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 56, 158, 67, 24, 4, 0, 0, 0, 15, - 0, 0, 0, 232, 255, 255, 255, 0, 0, 0, 0, 8, 0, 42, 14, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = -24; - test_msg.e = 15; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 4; - test_msg.n_sats = 8; - test_msg.tow = 407084600; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -24) - << "incorrect value for last_msg_.d, expected -24, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 15) - << "incorrect value for last_msg_.e, expected 15, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 4) - << "incorrect value for last_msg_.n, expected 4, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084600) - << "incorrect value for last_msg_.tow, expected 407084600, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA7, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 156, 158, 67, 24, 251, 255, 255, 255, 232, - 255, 255, 255, 247, 255, 255, 255, 0, 0, 0, 0, 8, 0, 218, 148, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = -9; - test_msg.e = -24; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -5; - test_msg.n_sats = 8; - test_msg.tow = 407084700; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -9) - << "incorrect value for last_msg_.d, expected -9, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -24) - << "incorrect value for last_msg_.e, expected -24, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -5) - << "incorrect value for last_msg_.n, expected -5, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084700) - << "incorrect value for last_msg_.tow, expected 407084700, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA8, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 0, 159, 67, 24, 10, 0, 0, 0, 2, - 0, 0, 0, 222, 255, 255, 255, 0, 0, 0, 0, 8, 0, 148, 16, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = -34; - test_msg.e = 2; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = 10; - test_msg.n_sats = 8; - test_msg.tow = 407084800; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -34) - << "incorrect value for last_msg_.d, expected -34, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 2) - << "incorrect value for last_msg_.e, expected 2, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, 10) - << "incorrect value for last_msg_.n, expected 10, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084800) - << "incorrect value for last_msg_.tow, expected 407084800, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA9, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 100, 159, 67, 24, 248, 255, 255, 255, 254, - 255, 255, 255, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 255, 236, + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = 7; - test_msg.e = -2; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -8; - test_msg.n_sats = 8; - test_msg.tow = 407084900; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, 7) - << "incorrect value for last_msg_.d, expected 7, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -2) - << "incorrect value for last_msg_.e, expected -2, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -8) - << "incorrect value for last_msg_.n, expected -8, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 8) - << "incorrect value for last_msg_.n_sats, expected 8, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407084900) - << "incorrect value for last_msg_.tow, expected 407084900, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; -} -class Test_auto_check_sbp_navigation_MsgVelNEDDepA10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_navigation_MsgVelNEDDepA10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xa07d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_navigation_MsgVelNEDDepA10, Test) { - uint8_t encoded_frame[] = { - 85, 5, 2, 195, 4, 22, 46, 162, 68, 24, 255, 255, 255, 255, 253, - 255, 255, 255, 148, 255, 255, 255, 0, 0, 0, 0, 5, 0, 166, 189, + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 246, 215, 22, 120, 46, 39, 0, 14, 252, 255, 255, 207, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 125, 160, }; + uint8_t encoded_payload_[22] = { + 120, 46, 39, 0, 14, 252, 255, 255, 207, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; - sbp_msg_vel_ned_dep_a_t test_msg{}; - test_msg.d = -108; - test_msg.e = -3; - test_msg.flags = 0; - test_msg.h_accuracy = 0; - test_msg.n = -1; - test_msg.n_sats = 5; - test_msg.tow = 407151150; - test_msg.v_accuracy = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -108) - << "incorrect value for last_msg_.d, expected -108, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, -3) - << "incorrect value for last_msg_.e, expected -3, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 0) - << "incorrect value for last_msg_.h_accuracy, expected 0, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -1) - << "incorrect value for last_msg_.n, expected -1, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 5) - << "incorrect value for last_msg_.n_sats, expected 5, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 407151150) - << "incorrect value for last_msg_.tow, expected 407151150, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 0) - << "incorrect value for last_msg_.v_accuracy, expected 0, is " - << last_msg_.v_accuracy; + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA2() { + assign(test_msg_.d, 0); + assign(test_msg_.e, 3724); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -976); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2567900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x87b3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 246, 215, 22, 220, 46, 39, 0, 48, 252, 255, 255, 140, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 179, 135, + }; + uint8_t encoded_payload_[22] = { + 220, 46, 39, 0, 48, 252, 255, 255, 140, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA3() { + assign(test_msg_.d, 0); + assign(test_msg_.e, 3848); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -992); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568000); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xb133; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 246, 215, 22, 64, 47, 39, 0, 32, 252, 255, 255, 8, + 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 51, 177, + }; + uint8_t encoded_payload_[22] = { + 64, 47, 39, 0, 32, 252, 255, 255, 8, 15, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA4() { + assign(test_msg_.d, 0); + assign(test_msg_.e, 3724); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -944); + assign(test_msg_.n_sats, 9); + assign(test_msg_.tow, 2568100); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x17; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 246, 215, 22, 164, 47, 39, 0, 80, 252, 255, 255, 140, + 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 23, 0, + }; + uint8_t encoded_payload_[22] = { + 164, 47, 39, 0, 80, 252, 255, 255, 140, 14, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA5() { + assign(test_msg_.d, 25); + assign(test_msg_.e, 26); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -27); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084500); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x1984; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 212, 157, 67, 24, 229, 255, 255, 255, 26, + 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, 0, 8, 0, 132, 25, + }; + uint8_t encoded_payload_[22] = { + 212, 157, 67, 24, 229, 255, 255, 255, 26, 0, 0, + 0, 25, 0, 0, 0, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA6 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA6() { + assign(test_msg_.d, -24); + assign(test_msg_.e, 15); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 4); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084600); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xe2a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 56, 158, 67, 24, 4, 0, 0, 0, 15, + 0, 0, 0, 232, 255, 255, 255, 0, 0, 0, 0, 8, 0, 42, 14, + }; + uint8_t encoded_payload_[22] = { + 56, 158, 67, 24, 4, 0, 0, 0, 15, 0, 0, + 0, 232, 255, 255, 255, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA7 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA7() { + assign(test_msg_.d, -9); + assign(test_msg_.e, -24); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -5); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084700); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x94da; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 156, 158, 67, 24, 251, 255, 255, 255, 232, + 255, 255, 255, 247, 255, 255, 255, 0, 0, 0, 0, 8, 0, 218, 148, + }; + uint8_t encoded_payload_[22] = { + 156, 158, 67, 24, 251, 255, 255, 255, 232, 255, 255, + 255, 247, 255, 255, 255, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA8 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA8() { + assign(test_msg_.d, -34); + assign(test_msg_.e, 2); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, 10); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084800); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x1094; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 0, 159, 67, 24, 10, 0, 0, 0, 2, + 0, 0, 0, 222, 255, 255, 255, 0, 0, 0, 0, 8, 0, 148, 16, + }; + uint8_t encoded_payload_[22] = { + 0, 159, 67, 24, 10, 0, 0, 0, 2, 0, 0, + 0, 222, 255, 255, 255, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA9 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA9() { + assign(test_msg_.d, 7); + assign(test_msg_.e, -2); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -8); + assign(test_msg_.n_sats, 8); + assign(test_msg_.tow, 407084900); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xecff; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 100, 159, 67, 24, 248, 255, 255, 255, 254, + 255, 255, 255, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 255, 236, + }; + uint8_t encoded_payload_[22] = { + 100, 159, 67, 24, 248, 255, 255, 255, 254, 255, 255, + 255, 7, 0, 0, 0, 0, 0, 0, 0, 8, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_navigation_MsgVelNEDDepA10 : public ::testing::Test { + public: + Testauto_check_sbp_navigation_MsgVelNEDDepA10() { + assign(test_msg_.d, -108); + assign(test_msg_.e, -3); + assign(test_msg_.flags, 0); + assign(test_msg_.h_accuracy, 0); + assign(test_msg_.n, -1); + assign(test_msg_.n_sats, 5); + assign(test_msg_.tow, 407151150); + assign(test_msg_.v_accuracy, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_dep_a, + sizeof(msg->vel_ned_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xbda6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_vel_ned_dep_a_t &lesser, + const sbp_msg_vel_ned_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_dep_a_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { + 85, 5, 2, 195, 4, 22, 46, 162, 68, 24, 255, 255, 255, 255, 253, + 255, 255, 255, 148, 255, 255, 255, 0, 0, 0, 0, 5, 0, 166, 189, + }; + uint8_t encoded_payload_[22] = { + 46, 162, 68, 24, 255, 255, 255, 255, 253, 255, 255, + 255, 148, 255, 255, 255, 0, 0, 0, 0, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_dep_a_t lesser = info.test_msg; + sbp_msg_vel_ned_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_DEP_A"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNEDDepA10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelNedCovGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelNedCovGnss.cc index 4f72fffbe8..eaf3233601 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelNedCovGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelNedCovGnss.cc @@ -16,133 +16,661 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelNedCovGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelNedCovGnss0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNedCovGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNedCovGnss0() { + assign(test_msg_.cov_d_d, 0.007882959209382534); + assign(test_msg_.cov_e_d, 0.00016467059322167188); + assign(test_msg_.cov_e_e, 0.0009897587588056922); + assign(test_msg_.cov_n_d, 0.00017716512957122177); + assign(test_msg_.cov_n_e, 1.457612233934924e-05); + assign(test_msg_.cov_n_n, 0.0015810149488970637); + assign(test_msg_.d, -10); + assign(test_msg_.e, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.n, -5); + assign(test_msg_.n_sats, 21); + assign(test_msg_.tow, 501868200); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_cov_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_cov_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedCovGnss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_cov_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedCovGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_cov_gnss, + sizeof(msg->vel_ned_cov_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_cov_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_cov_gnss, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedCovGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0x39b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 42; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_cov_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_cov_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_cov_gnss_t &lesser, + const sbp_msg_vel_ned_cov_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_cov_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_cov_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedCovGnss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgVelNedCovGnss, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedCovGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedCovGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNedCovGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_cov_gnss_t test_msg_{}; + uint8_t encoded_frame_[42 + 8] = { 85, 50, 2, 0, 16, 42, 168, 230, 233, 29, 251, 255, 255, 255, 0, 0, 0, 0, 246, 255, 255, 255, 15, 58, 207, 58, 248, 139, 116, 55, 103, 197, 57, 57, 203, 186, 129, 58, 109, 171, 44, 57, 135, 39, 1, 60, 21, 2, 155, 3, }; + uint8_t encoded_payload_[42] = { + 168, 230, 233, 29, 251, 255, 255, 255, 0, 0, 0, 0, 246, 255, + 255, 255, 15, 58, 207, 58, 248, 139, 116, 55, 103, 197, 57, 57, + 203, 186, 129, 58, 109, 171, 44, 57, 135, 39, 1, 60, 21, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgVelNedCovGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedCovGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + + for (uint8_t i = 0; i < 42; i++) { + EXPECT_EQ( + sbp_msg_vel_ned_cov_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedCovGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_cov_gnss_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedCovGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_vel_ned_cov_gnss_t test_msg{}; - test_msg.cov_d_d = 0.007882959209382534; - test_msg.cov_e_d = 0.00016467059322167188; - test_msg.cov_e_e = 0.0009897587588056922; - test_msg.cov_n_d = 0.00017716512957122177; - test_msg.cov_n_e = 1.457612233934924e-05; - test_msg.cov_n_n = 0.0015810149488970637; - test_msg.d = -10; - test_msg.e = 0; - test_msg.flags = 2; - test_msg.n = -5; - test_msg.n_sats = 21; - test_msg.tow = 501868200; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.cov_d_d * 100 - 0.00788295920938 * 100), 0.05) - << "incorrect value for last_msg_.cov_d_d, expected 0.00788295920938, is " - << last_msg_.cov_d_d; - EXPECT_LT((last_msg_.cov_e_d * 100 - 0.000164670593222 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_d, expected 0.000164670593222, " - "is " - << last_msg_.cov_e_d; - EXPECT_LT((last_msg_.cov_e_e * 100 - 0.000989758758806 * 100), 0.05) - << "incorrect value for last_msg_.cov_e_e, expected 0.000989758758806, " - "is " - << last_msg_.cov_e_e; - EXPECT_LT((last_msg_.cov_n_d * 100 - 0.000177165129571 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_d, expected 0.000177165129571, " - "is " - << last_msg_.cov_n_d; - EXPECT_LT((last_msg_.cov_n_e * 100 - 1.45761223393e-05 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_e, expected 1.45761223393e-05, " - "is " - << last_msg_.cov_n_e; - EXPECT_LT((last_msg_.cov_n_n * 100 - 0.0015810149489 * 100), 0.05) - << "incorrect value for last_msg_.cov_n_n, expected 0.0015810149489, is " - << last_msg_.cov_n_n; - EXPECT_EQ(last_msg_.d, -10) - << "incorrect value for last_msg_.d, expected -10, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 0) - << "incorrect value for last_msg_.e, expected 0, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n, -5) - << "incorrect value for last_msg_.n, expected -5, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 21) - << "incorrect value for last_msg_.n_sats, expected 21, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501868200) - << "incorrect value for last_msg_.tow, expected 501868200, is " - << last_msg_.tow; +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_d_d, greater.cov_d_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_d, greater.cov_e_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_e_e, greater.cov_e_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_d, greater.cov_n_d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_e, greater.cov_n_e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.cov_n_n, greater.cov_n_n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_cov_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_cov_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedCovGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_COV_GNSS"); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_cov_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_cov_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_cov_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.vel_ned_cov_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[42]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 42); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 42), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_cov_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 42); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedCovGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedCovGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedCovGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_navigation_MsgVelNedGnss.cc b/c/test/cpp/auto_check_sbp_navigation_MsgVelNedGnss.cc index 84cf898a38..052d5822d7 100644 --- a/c/test/cpp/auto_check_sbp_navigation_MsgVelNedGnss.cc +++ b/c/test/cpp/auto_check_sbp_navigation_MsgVelNedGnss.cc @@ -16,111 +16,620 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_navigation_MsgVelNedGnss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_navigation_MsgVelNedGnss0 : public ::testing::Test { public: - Test_auto_check_sbp_navigation_MsgVelNedGnss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_navigation_MsgVelNedGnss0() { + assign(test_msg_.d, -10); + assign(test_msg_.e, 0); + assign(test_msg_.flags, 2); + assign(test_msg_.h_accuracy, 40); + assign(test_msg_.n, -5); + assign(test_msg_.n_sats, 21); + assign(test_msg_.tow, 501868200); + assign(test_msg_.v_accuracy, 89); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_gnss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_vel_ned_gnss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgVelNedGnss, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_vel_ned_gnss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgVelNedGnss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->vel_ned_gnss, + sizeof(msg->vel_ned_gnss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_vel_ned_gnss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.vel_ned_gnss, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgVelNedGnss); + info.sender_id = 4096; + info.preamble = 0x55; + info.crc = 0xab63; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 22; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_vel_ned_gnss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_vel_ned_gnss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_vel_ned_gnss_t &lesser, + const sbp_msg_vel_ned_gnss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_vel_ned_gnss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_vel_ned_gnss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_vel_ned_gnss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_vel_ned_gnss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedGnss, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgVelNedGnss, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgVelNedGnss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgVelNedGnss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_navigation_MsgVelNedGnss0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_vel_ned_gnss_t test_msg_{}; + uint8_t encoded_frame_[22 + 8] = { 85, 46, 2, 0, 16, 22, 168, 230, 233, 29, 251, 255, 255, 255, 0, 0, 0, 0, 246, 255, 255, 255, 40, 0, 89, 0, 21, 2, 99, 171, }; + uint8_t encoded_payload_[22] = { + 168, 230, 233, 29, 251, 255, 255, 255, 0, 0, 0, + 0, 246, 255, 255, 255, 40, 0, 89, 0, 21, 2, + }; +}; + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_vel_ned_gnss_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgVelNedGnss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_vel_ned_gnss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgVelNedGnss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + EXPECT_EQ(sbp_msg_vel_ned_gnss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + + for (uint8_t i = 0; i < 22; i++) { + EXPECT_EQ(sbp_msg_vel_ned_gnss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_vel_ned_gnss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgVelNedGnss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_vel_ned_gnss_t test_msg{}; - test_msg.d = -10; - test_msg.e = 0; - test_msg.flags = 2; - test_msg.h_accuracy = 40; - test_msg.n = -5; - test_msg.n_sats = 21; - test_msg.tow = 501868200; - test_msg.v_accuracy = 89; - - EXPECT_EQ(send_message(4096, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 4096); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.d, -10) - << "incorrect value for last_msg_.d, expected -10, is " << last_msg_.d; - EXPECT_EQ(last_msg_.e, 0) - << "incorrect value for last_msg_.e, expected 0, is " << last_msg_.e; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.h_accuracy, 40) - << "incorrect value for last_msg_.h_accuracy, expected 40, is " - << last_msg_.h_accuracy; - EXPECT_EQ(last_msg_.n, -5) - << "incorrect value for last_msg_.n, expected -5, is " << last_msg_.n; - EXPECT_EQ(last_msg_.n_sats, 21) - << "incorrect value for last_msg_.n_sats, expected 21, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.tow, 501868200) - << "incorrect value for last_msg_.tow, expected 501868200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.v_accuracy, 89) - << "incorrect value for last_msg_.v_accuracy, expected 89, is " - << last_msg_.v_accuracy; +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_gnss_t msg{}; + + EXPECT_EQ(sbp_msg_vel_ned_gnss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_gnss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_vel_ned_gnss_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_vel_ned_gnss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgVelNedGnss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.d, greater.d); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.e, greater.e); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.h_accuracy, greater.h_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n, greater.n); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_vel_ned_gnss_t lesser = info.test_msg; + sbp_msg_vel_ned_gnss_t greater = info.test_msg; + make_lesser_greater(lesser.v_accuracy, greater.v_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgVelNedGnss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_VEL_NED_GNSS"); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_vel_ned_gnss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_vel_ned_gnss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.vel_ned_gnss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.vel_ned_gnss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[22]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 22); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 22), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_vel_ned_gnss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 22); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgVelNedGnss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_navigation_MsgVelNedGnss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgVelNedGnss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgBasePosEcef.cc b/c/test/cpp/auto_check_sbp_observation_MsgBasePosEcef.cc index 9b1dd0cc60..4e6795fea6 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgBasePosEcef.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgBasePosEcef.cc @@ -16,95 +16,589 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgBasePosEcef0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgBasePosEcef0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgBasePosEcef0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_observation_MsgBasePosEcef0() { + assign(test_msg_.x, -2726575.9189); + assign(test_msg_.y, -4315267.2798); + assign(test_msg_.z, 3811455.9642); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_base_pos_ecef_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_base_pos_ecef_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgBasePosEcef, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_base_pos_ecef_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgBasePosEcef); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->base_pos_ecef, + sizeof(msg->base_pos_ecef)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_base_pos_ecef_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.base_pos_ecef, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgBasePosEcef); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0x7dc2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 24; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_base_pos_ecef_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_base_pos_ecef_t &lesser, + const sbp_msg_base_pos_ecef_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_base_pos_ecef_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_base_pos_ecef_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_base_pos_ecef_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_base_pos_ecef_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgBasePosEcef, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgBasePosEcef, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgBasePosEcef, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgBasePosEcef, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_base_pos_ecef_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_observation_MsgBasePosEcef0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_base_pos_ecef_t test_msg_{}; + uint8_t encoded_frame_[24 + 8] = { 85, 72, 0, 0, 0, 24, 228, 131, 158, 245, 87, 205, 68, 193, 66, 62, 232, 209, 32, 118, 80, 193, 213, 231, 106, 251, 63, 20, 77, 65, 194, 125, }; + uint8_t encoded_payload_[24] = { + 228, 131, 158, 245, 87, 205, 68, 193, 66, 62, 232, 209, + 32, 118, 80, 193, 213, 231, 106, 251, 63, 20, 77, 65, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_base_pos_ecef_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgBasePosEcef, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[24]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_base_pos_ecef_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 24); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 24), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgBasePosEcef, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 24); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 24), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[24]; + + EXPECT_EQ(sbp_msg_base_pos_ecef_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 24), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[24]; + + for (uint8_t i = 0; i < 24; i++) { + EXPECT_EQ(sbp_msg_base_pos_ecef_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_base_pos_ecef_t msg{}; + uint8_t n_read; - sbp_msg_base_pos_ecef_t test_msg{}; - test_msg.x = -2726575.9189; - test_msg.y = -4315267.2798; - test_msg.z = 3811455.9642; + EXPECT_EQ(sbp_msg_base_pos_ecef_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 24); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(send_message(0, test_msg), SBP_OK); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgBasePosEcef, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 24); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_base_pos_ecef_t msg{}; + + EXPECT_EQ(sbp_msg_base_pos_ecef_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_base_pos_ecef_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_base_pos_ecef_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_base_pos_ecef_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgBasePosEcef, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_base_pos_ecef_t lesser = info.test_msg; + sbp_msg_base_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_base_pos_ecef_t lesser = info.test_msg; + sbp_msg_base_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_base_pos_ecef_t lesser = info.test_msg; + sbp_msg_base_pos_ecef_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgBasePosEcef); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_BASE_POS_ECEF"); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_base_pos_ecef_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_base_pos_ecef_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.base_pos_ecef, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.base_pos_ecef, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[24]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 24); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 24), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_base_pos_ecef_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 24); + EXPECT_EQ(msg, info.test_msg); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.x * 100 - -2726575.9189 * 100), 0.05) - << "incorrect value for last_msg_.x, expected -2726575.9189, is " - << last_msg_.x; - EXPECT_LT((last_msg_.y * 100 - -4315267.2798 * 100), 0.05) - << "incorrect value for last_msg_.y, expected -4315267.2798, is " - << last_msg_.y; - EXPECT_LT((last_msg_.z * 100 - 3811455.9642 * 100), 0.05) - << "incorrect value for last_msg_.z, expected 3811455.9642, is " - << last_msg_.z; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgBasePosEcef, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgBasePosEcef0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgBasePosEcef, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisBds.cc b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisBds.cc index fd30f33a7b..39b4d2da91 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisBds.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisBds.cc @@ -16,66 +16,307 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgEphemerisBds0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgEphemerisBds0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgEphemerisBds0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgEphemerisBds0() { + assign(test_msg_.af0, -0.0008911322802305222); + assign(test_msg_.af1, 1.2398970739013748e-12); + assign(test_msg_.af2, -7.318364664277155e-19); + assign(test_msg_.c_ic, -6.658956408500671e-08); + assign(test_msg_.c_is, 3.5529956221580505e-07); + assign(test_msg_.c_rc, 234.640625); + assign(test_msg_.c_rs, 224.4375); + assign(test_msg_.c_uc, 7.606577128171921e-06); + assign(test_msg_.c_us, 6.551854312419891e-07); + assign(test_msg_.common.fit_interval, 10800); + assign(test_msg_.common.health_bits, 0); + assign(test_msg_.common.sid.code, 12); + assign(test_msg_.common.sid.sat, 8); + assign(test_msg_.common.toe.tow, 439214); + assign(test_msg_.common.toe.wn, 2154); + assign(test_msg_.common.ura, 2.0); + assign(test_msg_.common.valid, 1); + assign(test_msg_.dn, 1.1296899132622133e-09); + assign(test_msg_.ecc, 0.005184737499803305); + assign(test_msg_.inc, 1.0421769543504915); + assign(test_msg_.inc_dot, 7.507455572801683e-10); + assign(test_msg_.iodc, 5); + assign(test_msg_.iode, 6); + assign(test_msg_.m0, 1.6943958190727237); + assign(test_msg_.omega0, -2.581073762870982); + assign(test_msg_.omegadot, -2.303310227830545e-09); + assign(test_msg_.sqrta, 6493.49845123291); + assign(test_msg_.tgd1, 1.0499999980595476e-08); + assign(test_msg_.tgd2, -1.0999999799921056e-09); + assign(test_msg_.toc.tow, 439214); + assign(test_msg_.toc.wn, 2154); + assign(test_msg_.w, -2.698603205735458); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_bds_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_bds_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisBds, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_bds_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisBds); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_bds, + sizeof(msg->ephemeris_bds)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_bds_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_bds, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisBds); + info.sender_id = 61568; + info.preamble = 0x55; + info.crc = 0xf99d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 147; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_bds_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_bds_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_bds_t &lesser, + const sbp_msg_ephemeris_bds_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_bds_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_bds_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_bds_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_bds_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisBds, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisBds, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisBds, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisBds, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgEphemerisBds0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_bds_t test_msg_{}; + uint8_t encoded_frame_[147 + 8] = { 85, 137, 0, 128, 240, 147, 8, 12, 174, 179, 6, 0, 106, 8, 0, 0, 0, 64, 48, 42, 0, 0, 1, 0, 125, 99, 52, 50, 207, 46, 151, 176, 0, 112, 96, 67, 0, 164, 106, 67, 0, 60, 255, 54, 0, @@ -88,149 +329,499 @@ TEST_F(Test_auto_check_sbp_observation_MsgEphemerisBds0, Test) { 191, 0, 128, 174, 43, 0, 0, 88, 161, 174, 179, 6, 0, 106, 8, 6, 5, 0, 157, 249, }; + uint8_t encoded_payload_[147] = { + 8, 12, 174, 179, 6, 0, 106, 8, 0, 0, 0, 64, 48, 42, 0, + 0, 1, 0, 125, 99, 52, 50, 207, 46, 151, 176, 0, 112, 96, 67, + 0, 164, 106, 67, 0, 60, 255, 54, 0, 224, 47, 53, 0, 0, 143, + 179, 0, 192, 190, 52, 146, 101, 162, 196, 109, 104, 19, 62, 253, 87, + 86, 202, 62, 28, 251, 63, 0, 0, 0, 96, 151, 60, 117, 63, 0, + 0, 128, 154, 127, 93, 185, 64, 151, 193, 64, 0, 10, 166, 4, 192, + 160, 75, 174, 98, 8, 201, 35, 190, 205, 29, 12, 71, 189, 150, 5, + 192, 176, 72, 249, 189, 193, 172, 240, 63, 72, 249, 188, 180, 160, 203, + 9, 62, 0, 0, 0, 0, 92, 51, 77, 191, 0, 128, 174, 43, 0, + 0, 88, 161, 174, 179, 6, 0, 106, 8, 6, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_bds_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEphemerisBds, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[147]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_bds_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 147); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 147), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisBds, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 147); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 147), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[147]; + + EXPECT_EQ(sbp_msg_ephemeris_bds_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 147), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[147]; + + for (uint8_t i = 0; i < 147; i++) { + EXPECT_EQ(sbp_msg_ephemeris_bds_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_bds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_bds_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 147); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisBds, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 147); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_bds_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_bds_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_bds_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_bds_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_ephemeris_bds_t test_msg{}; - test_msg.af0 = -0.0008911322802305222; - test_msg.af1 = 1.2398970739013748e-12; - test_msg.af2 = -7.318364664277155e-19; - test_msg.c_ic = -6.658956408500671e-08; - test_msg.c_is = 3.5529956221580505e-07; - test_msg.c_rc = 234.640625; - test_msg.c_rs = 224.4375; - test_msg.c_uc = 7.606577128171921e-06; - test_msg.c_us = 6.551854312419891e-07; - test_msg.common.fit_interval = 10800; - test_msg.common.health_bits = 0; - test_msg.common.sid.code = 12; - test_msg.common.sid.sat = 8; - test_msg.common.toe.tow = 439214; - test_msg.common.toe.wn = 2154; - test_msg.common.ura = 2.0; - test_msg.common.valid = 1; - test_msg.dn = 1.1296899132622133e-09; - test_msg.ecc = 0.005184737499803305; - test_msg.inc = 1.0421769543504915; - test_msg.inc_dot = 7.507455572801683e-10; - test_msg.iodc = 5; - test_msg.iode = 6; - test_msg.m0 = 1.6943958190727237; - test_msg.omega0 = -2.581073762870982; - test_msg.omegadot = -2.303310227830545e-09; - test_msg.sqrta = 6493.49845123291; - test_msg.tgd1 = 1.0499999980595476e-08; - test_msg.tgd2 = -1.0999999799921056e-09; - test_msg.toc.tow = 439214; - test_msg.toc.wn = 2154; - test_msg.w = -2.698603205735458; - - EXPECT_EQ(send_message(61568, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61568); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -0.000891132280231 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -0.000891132280231, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - 1.2398970739e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected 1.2398970739e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - -7.31836466428e-19 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected -7.31836466428e-19, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - -6.6589564085e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected -6.6589564085e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - 3.55299562216e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected 3.55299562216e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 234.640625 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 234.640625, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - 224.4375 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected 224.4375, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - 7.60657712817e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected 7.60657712817e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 6.55185431242e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 6.55185431242e-07, is " - << last_msg_.c_us; - EXPECT_EQ(last_msg_.common.fit_interval, 10800) - << "incorrect value for last_msg_.common.fit_interval, expected 10800, " - "is " - << last_msg_.common.fit_interval; - EXPECT_EQ(last_msg_.common.health_bits, 0) - << "incorrect value for last_msg_.common.health_bits, expected 0, is " - << last_msg_.common.health_bits; - EXPECT_EQ(last_msg_.common.sid.code, 12) - << "incorrect value for last_msg_.common.sid.code, expected 12, is " - << last_msg_.common.sid.code; - EXPECT_EQ(last_msg_.common.sid.sat, 8) - << "incorrect value for last_msg_.common.sid.sat, expected 8, is " - << last_msg_.common.sid.sat; - EXPECT_EQ(last_msg_.common.toe.tow, 439214) - << "incorrect value for last_msg_.common.toe.tow, expected 439214, is " - << last_msg_.common.toe.tow; - EXPECT_EQ(last_msg_.common.toe.wn, 2154) - << "incorrect value for last_msg_.common.toe.wn, expected 2154, is " - << last_msg_.common.toe.wn; - EXPECT_LT((last_msg_.common.ura * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.common.ura, expected 2.0, is " - << last_msg_.common.ura; - EXPECT_EQ(last_msg_.common.valid, 1) - << "incorrect value for last_msg_.common.valid, expected 1, is " - << last_msg_.common.valid; - EXPECT_LT((last_msg_.dn * 100 - 1.12968991326e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 1.12968991326e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.0051847374998 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.0051847374998, is " - << last_msg_.ecc; - EXPECT_LT((last_msg_.inc * 100 - 1.04217695435 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 1.04217695435, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - 7.5074555728e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected 7.5074555728e-10, is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iodc, 5) - << "incorrect value for last_msg_.iodc, expected 5, is " - << last_msg_.iodc; - EXPECT_EQ(last_msg_.iode, 6) - << "incorrect value for last_msg_.iode, expected 6, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - 1.69439581907 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected 1.69439581907, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - -2.58107376287 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected -2.58107376287, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -2.30331022783e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -2.30331022783e-09, " - "is " - << last_msg_.omegadot; - EXPECT_LT((last_msg_.sqrta * 100 - 6493.49845123 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 6493.49845123, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd1 * 100 - 1.04999999806e-08 * 100), 0.05) - << "incorrect value for last_msg_.tgd1, expected 1.04999999806e-08, is " - << last_msg_.tgd1; - EXPECT_LT((last_msg_.tgd2 * 100 - -1.09999997999e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd2, expected -1.09999997999e-09, is " - << last_msg_.tgd2; - EXPECT_EQ(last_msg_.toc.tow, 439214) - << "incorrect value for last_msg_.toc.tow, expected 439214, is " - << last_msg_.toc.tow; - EXPECT_EQ(last_msg_.toc.wn, 2154) - << "incorrect value for last_msg_.toc.wn, expected 2154, is " - << last_msg_.toc.wn; - EXPECT_LT((last_msg_.w * 100 - -2.69860320574 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -2.69860320574, is " - << last_msg_.w; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_bds_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisBds, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.fit_interval, + greater.common.fit_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.health_bits, greater.common.health_bits); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.code, greater.common.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.sat, greater.common.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.tow, greater.common.toe.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.wn, greater.common.toe.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.ura, greater.common.ura); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.common.valid, greater.common.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.iodc, greater.iodc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.tgd1, greater.tgd1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.tgd2, greater.tgd2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.toc.tow, greater.toc.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.toc.wn, greater.toc.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_bds_t lesser = info.test_msg; + sbp_msg_ephemeris_bds_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisBds); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_BDS"); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_bds_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_bds_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_bds, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ephemeris_bds, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[147]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 147); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 147), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_bds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 147); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisBds, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisBds0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisBds, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGLO.cc b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGLO.cc index 04530b2cf3..36ed234ab7 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGLO.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGLO.cc @@ -16,66 +16,305 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgEphemerisGLO0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgEphemerisGLO0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgEphemerisGLO0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgEphemerisGLO0() { + assign(test_msg_.acc[0], 9.313225746154785e-07); + + assign(test_msg_.acc[1], 9.313225746154785e-07); + + assign(test_msg_.acc[2], 2.7939677238464355e-06); + assign(test_msg_.common.fit_interval, 2400); + assign(test_msg_.common.health_bits, 0); + assign(test_msg_.common.sid.code, 3); + assign(test_msg_.common.sid.sat, 4); + assign(test_msg_.common.toe.tow, 443718); + assign(test_msg_.common.toe.wn, 2154); + assign(test_msg_.common.ura, 5.0); + assign(test_msg_.common.valid, 1); + assign(test_msg_.d_tau, -2.7939677238464355e-09); + assign(test_msg_.fcn, 14); + assign(test_msg_.gamma, 9.094947017729282e-13); + assign(test_msg_.iod, 100); + + assign(test_msg_.pos[0], -12177330.078125); + + assign(test_msg_.pos[1], 599893.06640625); + + assign(test_msg_.pos[2], -22373708.49609375); + assign(test_msg_.tau, -8.36281105875969e-05); + + assign(test_msg_.vel[0], -1726.506233215332); + + assign(test_msg_.vel[1], -2542.6149368286133); + + assign(test_msg_.vel[2], 869.8177337646484); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_glo_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_glo_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisGlo, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_glo_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisGlo); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_glo, + sizeof(msg->ephemeris_glo)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_glo_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_glo, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisGlo); + info.sender_id = 2314; + info.preamble = 0x55; + info.crc = 0x9559; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 92; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_glo_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_glo_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_glo_t &lesser, + const sbp_msg_ephemeris_glo_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_glo_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_glo_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_glo_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_glo_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGlo, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGlo, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisGlo, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisGlo, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGLO0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_glo_t test_msg_{}; + uint8_t encoded_frame_[92 + 8] = { 85, 139, 0, 10, 9, 92, 4, 3, 70, 197, 6, 0, 106, 8, 0, 0, 160, 64, 96, 9, 0, 0, 1, 0, 0, 0, 128, 43, 128, 97, 175, 184, 0, 0, 64, 177, 0, 0, 128, 66, 246, 57, 103, 193, 0, @@ -84,115 +323,445 @@ TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGLO0, Test) { 192, 0, 0, 0, 184, 138, 46, 139, 64, 0, 0, 122, 53, 0, 0, 122, 53, 0, 128, 59, 54, 14, 100, 89, 149, }; + uint8_t encoded_payload_[92] = { + 4, 3, 70, 197, 6, 0, 106, 8, 0, 0, 160, 64, 96, 9, + 0, 0, 1, 0, 0, 0, 128, 43, 128, 97, 175, 184, 0, 0, + 64, 177, 0, 0, 128, 66, 246, 57, 103, 193, 0, 0, 0, 34, + 170, 78, 34, 65, 0, 0, 240, 199, 84, 86, 117, 193, 0, 0, + 0, 98, 6, 250, 154, 192, 0, 0, 0, 217, 58, 221, 163, 192, + 0, 0, 0, 184, 138, 46, 139, 64, 0, 0, 122, 53, 0, 0, + 122, 53, 0, 128, 59, 54, 14, 100, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_glo_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEphemerisGlo, &info.test_msg_wrapped), + info.payload_len); +} - sbp_msg_ephemeris_glo_t test_msg{}; - - test_msg.acc[0] = 9.313225746154785e-07; - - test_msg.acc[1] = 9.313225746154785e-07; - - test_msg.acc[2] = 2.7939677238464355e-06; - test_msg.common.fit_interval = 2400; - test_msg.common.health_bits = 0; - test_msg.common.sid.code = 3; - test_msg.common.sid.sat = 4; - test_msg.common.toe.tow = 443718; - test_msg.common.toe.wn = 2154; - test_msg.common.ura = 5.0; - test_msg.common.valid = 1; - test_msg.d_tau = -2.7939677238464355e-09; - test_msg.fcn = 14; - test_msg.gamma = 9.094947017729282e-13; - test_msg.iod = 100; - - test_msg.pos[0] = -12177330.078125; - - test_msg.pos[1] = 599893.06640625; - - test_msg.pos[2] = -22373708.49609375; - test_msg.tau = -8.36281105875969e-05; - - test_msg.vel[0] = -1726.506233215332; - - test_msg.vel[1] = -2542.6149368286133; - - test_msg.vel[2] = 869.8177337646484; - - EXPECT_EQ(send_message(2314, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 2314); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.acc[0] * 100 - 9.31322574615e-07 * 100), 0.05) - << "incorrect value for last_msg_.acc[0], expected 9.31322574615e-07, is " - << last_msg_.acc[0]; - EXPECT_LT((last_msg_.acc[1] * 100 - 9.31322574615e-07 * 100), 0.05) - << "incorrect value for last_msg_.acc[1], expected 9.31322574615e-07, is " - << last_msg_.acc[1]; - EXPECT_LT((last_msg_.acc[2] * 100 - 2.79396772385e-06 * 100), 0.05) - << "incorrect value for last_msg_.acc[2], expected 2.79396772385e-06, is " - << last_msg_.acc[2]; - EXPECT_EQ(last_msg_.common.fit_interval, 2400) - << "incorrect value for last_msg_.common.fit_interval, expected 2400, is " - << last_msg_.common.fit_interval; - EXPECT_EQ(last_msg_.common.health_bits, 0) - << "incorrect value for last_msg_.common.health_bits, expected 0, is " - << last_msg_.common.health_bits; - EXPECT_EQ(last_msg_.common.sid.code, 3) - << "incorrect value for last_msg_.common.sid.code, expected 3, is " - << last_msg_.common.sid.code; - EXPECT_EQ(last_msg_.common.sid.sat, 4) - << "incorrect value for last_msg_.common.sid.sat, expected 4, is " - << last_msg_.common.sid.sat; - EXPECT_EQ(last_msg_.common.toe.tow, 443718) - << "incorrect value for last_msg_.common.toe.tow, expected 443718, is " - << last_msg_.common.toe.tow; - EXPECT_EQ(last_msg_.common.toe.wn, 2154) - << "incorrect value for last_msg_.common.toe.wn, expected 2154, is " - << last_msg_.common.toe.wn; - EXPECT_LT((last_msg_.common.ura * 100 - 5.0 * 100), 0.05) - << "incorrect value for last_msg_.common.ura, expected 5.0, is " - << last_msg_.common.ura; - EXPECT_EQ(last_msg_.common.valid, 1) - << "incorrect value for last_msg_.common.valid, expected 1, is " - << last_msg_.common.valid; - EXPECT_LT((last_msg_.d_tau * 100 - -2.79396772385e-09 * 100), 0.05) - << "incorrect value for last_msg_.d_tau, expected -2.79396772385e-09, is " - << last_msg_.d_tau; - EXPECT_EQ(last_msg_.fcn, 14) - << "incorrect value for last_msg_.fcn, expected 14, is " << last_msg_.fcn; - EXPECT_LT((last_msg_.gamma * 100 - 9.09494701773e-13 * 100), 0.05) - << "incorrect value for last_msg_.gamma, expected 9.09494701773e-13, is " - << last_msg_.gamma; - EXPECT_EQ(last_msg_.iod, 100) - << "incorrect value for last_msg_.iod, expected 100, is " - << last_msg_.iod; - EXPECT_LT((last_msg_.pos[0] * 100 - -12177330.0781 * 100), 0.05) - << "incorrect value for last_msg_.pos[0], expected -12177330.0781, is " - << last_msg_.pos[0]; - EXPECT_LT((last_msg_.pos[1] * 100 - 599893.066406 * 100), 0.05) - << "incorrect value for last_msg_.pos[1], expected 599893.066406, is " - << last_msg_.pos[1]; - EXPECT_LT((last_msg_.pos[2] * 100 - -22373708.4961 * 100), 0.05) - << "incorrect value for last_msg_.pos[2], expected -22373708.4961, is " - << last_msg_.pos[2]; - EXPECT_LT((last_msg_.tau * 100 - -8.36281105876e-05 * 100), 0.05) - << "incorrect value for last_msg_.tau, expected -8.36281105876e-05, is " - << last_msg_.tau; - EXPECT_LT((last_msg_.vel[0] * 100 - -1726.50623322 * 100), 0.05) - << "incorrect value for last_msg_.vel[0], expected -1726.50623322, is " - << last_msg_.vel[0]; - EXPECT_LT((last_msg_.vel[1] * 100 - -2542.61493683 * 100), 0.05) - << "incorrect value for last_msg_.vel[1], expected -2542.61493683, is " - << last_msg_.vel[1]; - EXPECT_LT((last_msg_.vel[2] * 100 - 869.817733765 * 100), 0.05) - << "incorrect value for last_msg_.vel[2], expected 869.817733765, is " - << last_msg_.vel[2]; +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[92]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_glo_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 92); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 92), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisGlo, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 92); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 92), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[92]; + + EXPECT_EQ(sbp_msg_ephemeris_glo_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 92), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[92]; + + for (uint8_t i = 0; i < 92; i++) { + EXPECT_EQ(sbp_msg_ephemeris_glo_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_glo_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_glo_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 92); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisGlo, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 92); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_glo_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_glo_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_glo_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_glo_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_glo_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisGlo, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.acc[0], greater.acc[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.acc[1], greater.acc[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.acc[2], greater.acc[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.fit_interval, + greater.common.fit_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.health_bits, greater.common.health_bits); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.code, greater.common.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.sat, greater.common.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.tow, greater.common.toe.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.wn, greater.common.toe.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.ura, greater.common.ura); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.common.valid, greater.common.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.d_tau, greater.d_tau); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.fcn, greater.fcn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.gamma, greater.gamma); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.iod, greater.iod); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.pos[0], greater.pos[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.pos[1], greater.pos[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.pos[2], greater.pos[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.tau, greater.tau); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.vel[0], greater.vel[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.vel[1], greater.vel[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ephemeris_glo_t lesser = info.test_msg; + sbp_msg_ephemeris_glo_t greater = info.test_msg; + make_lesser_greater(lesser.vel[2], greater.vel[2]); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisGlo); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_GLO"); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_glo_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_glo_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_glo, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ephemeris_glo, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[92]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 92); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 92), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_glo_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 92); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisGlo, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGLO0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisGlo, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGPS.cc b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGPS.cc index ffa31e4f74..299a9af4d5 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGPS.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGPS.cc @@ -16,66 +16,306 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgEphemerisGPS0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgEphemerisGPS0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgEphemerisGPS0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgEphemerisGPS0() { + assign(test_msg_.af0, -0.0006315018981695175); + assign(test_msg_.af1, 8.981260180007666e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, 7.450580596923828e-09); + assign(test_msg_.c_is, -1.1548399925231934e-07); + assign(test_msg_.c_rc, 308.625); + assign(test_msg_.c_rs, -52.3125); + assign(test_msg_.c_uc, -2.7436763048171997e-06); + assign(test_msg_.c_us, 3.1366944313049316e-06); + assign(test_msg_.common.fit_interval, 14400); + assign(test_msg_.common.health_bits, 0); + assign(test_msg_.common.sid.code, 0); + assign(test_msg_.common.sid.sat, 22); + assign(test_msg_.common.toe.tow, 446384); + assign(test_msg_.common.toe.wn, 2154); + assign(test_msg_.common.ura, 2.0); + assign(test_msg_.common.valid, 1); + assign(test_msg_.dn, 5.694522914022375e-09); + assign(test_msg_.ecc, 0.007072207052260637); + assign(test_msg_.inc, 0.9341514480259797); + assign(test_msg_.inc_dot, -4.035882396415757e-11); + assign(test_msg_.iodc, 45); + assign(test_msg_.iode, 45); + assign(test_msg_.m0, -0.02200078842114688); + assign(test_msg_.omega0, -1.8731818448797617); + assign(test_msg_.omegadot, -8.903585155774196e-09); + assign(test_msg_.sqrta, 5153.550029754639); + assign(test_msg_.tgd, -1.7695128917694092e-08); + assign(test_msg_.toc.tow, 446384); + assign(test_msg_.toc.wn, 2154); + assign(test_msg_.w, -0.9893036629599647); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_gps_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_gps_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisGps, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_gps_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisGps); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_gps, + sizeof(msg->ephemeris_gps)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_gps_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_gps, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisGps); + info.sender_id = 2314; + info.preamble = 0x55; + info.crc = 0x4aa; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 139; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_gps_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_gps_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_gps_t &lesser, + const sbp_msg_ephemeris_gps_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_gps_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_gps_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_gps_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_gps_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGps, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGps, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisGps, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisGps, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGPS0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_gps_t test_msg_{}; + uint8_t encoded_frame_[139 + 8] = { 85, 138, 0, 10, 9, 139, 22, 0, 176, 207, 6, 0, 106, 8, 0, 0, 0, 64, 64, 56, 0, 0, 1, 0, 0, 0, 152, 178, 0, 64, 81, 194, 0, 80, 154, 67, 0, 32, 56, 182, 0, 128, 82, 54, 0, @@ -87,146 +327,493 @@ TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGPS0, Test) { 255, 47, 198, 189, 96, 139, 37, 186, 0, 0, 30, 45, 0, 0, 0, 0, 176, 207, 6, 0, 106, 8, 45, 45, 0, 170, 4, }; + uint8_t encoded_payload_[139] = { + 22, 0, 176, 207, 6, 0, 106, 8, 0, 0, 0, 64, 64, 56, + 0, 0, 1, 0, 0, 0, 152, 178, 0, 64, 81, 194, 0, 80, + 154, 67, 0, 32, 56, 182, 0, 128, 82, 54, 0, 0, 0, 50, + 0, 0, 248, 179, 114, 216, 96, 180, 49, 117, 56, 62, 142, 41, + 5, 235, 95, 135, 150, 191, 0, 0, 0, 32, 191, 247, 124, 63, + 0, 0, 192, 206, 140, 33, 180, 64, 41, 131, 179, 134, 141, 248, + 253, 191, 227, 133, 81, 54, 204, 30, 67, 190, 216, 59, 199, 39, + 96, 168, 239, 191, 71, 11, 217, 147, 145, 228, 237, 63, 221, 47, + 100, 224, 255, 47, 198, 189, 96, 139, 37, 186, 0, 0, 30, 45, + 0, 0, 0, 0, 176, 207, 6, 0, 106, 8, 45, 45, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_gps_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEphemerisGps, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_gps_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisGps, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + + EXPECT_EQ(sbp_msg_ephemeris_gps_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + + for (uint8_t i = 0; i < 139; i++) { + EXPECT_EQ(sbp_msg_ephemeris_gps_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gps_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_gps_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisGps, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gps_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_gps_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gps_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_gps_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_ephemeris_gps_t test_msg{}; - test_msg.af0 = -0.0006315018981695175; - test_msg.af1 = 8.981260180007666e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = 7.450580596923828e-09; - test_msg.c_is = -1.1548399925231934e-07; - test_msg.c_rc = 308.625; - test_msg.c_rs = -52.3125; - test_msg.c_uc = -2.7436763048171997e-06; - test_msg.c_us = 3.1366944313049316e-06; - test_msg.common.fit_interval = 14400; - test_msg.common.health_bits = 0; - test_msg.common.sid.code = 0; - test_msg.common.sid.sat = 22; - test_msg.common.toe.tow = 446384; - test_msg.common.toe.wn = 2154; - test_msg.common.ura = 2.0; - test_msg.common.valid = 1; - test_msg.dn = 5.694522914022375e-09; - test_msg.ecc = 0.007072207052260637; - test_msg.inc = 0.9341514480259797; - test_msg.inc_dot = -4.035882396415757e-11; - test_msg.iodc = 45; - test_msg.iode = 45; - test_msg.m0 = -0.02200078842114688; - test_msg.omega0 = -1.8731818448797617; - test_msg.omegadot = -8.903585155774196e-09; - test_msg.sqrta = 5153.550029754639; - test_msg.tgd = -1.7695128917694092e-08; - test_msg.toc.tow = 446384; - test_msg.toc.wn = 2154; - test_msg.w = -0.9893036629599647; - - EXPECT_EQ(send_message(2314, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 2314); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -0.00063150189817 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -0.00063150189817, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - 8.98126018001e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected 8.98126018001e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - 7.45058059692e-09 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected 7.45058059692e-09, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - -1.15483999252e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected -1.15483999252e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 308.625 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 308.625, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - -52.3125 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected -52.3125, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - -2.74367630482e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected -2.74367630482e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 3.1366944313e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 3.1366944313e-06, is " - << last_msg_.c_us; - EXPECT_EQ(last_msg_.common.fit_interval, 14400) - << "incorrect value for last_msg_.common.fit_interval, expected 14400, " - "is " - << last_msg_.common.fit_interval; - EXPECT_EQ(last_msg_.common.health_bits, 0) - << "incorrect value for last_msg_.common.health_bits, expected 0, is " - << last_msg_.common.health_bits; - EXPECT_EQ(last_msg_.common.sid.code, 0) - << "incorrect value for last_msg_.common.sid.code, expected 0, is " - << last_msg_.common.sid.code; - EXPECT_EQ(last_msg_.common.sid.sat, 22) - << "incorrect value for last_msg_.common.sid.sat, expected 22, is " - << last_msg_.common.sid.sat; - EXPECT_EQ(last_msg_.common.toe.tow, 446384) - << "incorrect value for last_msg_.common.toe.tow, expected 446384, is " - << last_msg_.common.toe.tow; - EXPECT_EQ(last_msg_.common.toe.wn, 2154) - << "incorrect value for last_msg_.common.toe.wn, expected 2154, is " - << last_msg_.common.toe.wn; - EXPECT_LT((last_msg_.common.ura * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.common.ura, expected 2.0, is " - << last_msg_.common.ura; - EXPECT_EQ(last_msg_.common.valid, 1) - << "incorrect value for last_msg_.common.valid, expected 1, is " - << last_msg_.common.valid; - EXPECT_LT((last_msg_.dn * 100 - 5.69452291402e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 5.69452291402e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00707220705226 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00707220705226, is " - << last_msg_.ecc; - EXPECT_LT((last_msg_.inc * 100 - 0.934151448026 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.934151448026, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - -4.03588239642e-11 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected -4.03588239642e-11, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iodc, 45) - << "incorrect value for last_msg_.iodc, expected 45, is " - << last_msg_.iodc; - EXPECT_EQ(last_msg_.iode, 45) - << "incorrect value for last_msg_.iode, expected 45, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - -0.0220007884211 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected -0.0220007884211, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - -1.87318184488 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected -1.87318184488, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.90358515577e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.90358515577e-09, " - "is " - << last_msg_.omegadot; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.55002975 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.55002975, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -1.76951289177e-08 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -1.76951289177e-08, is " - << last_msg_.tgd; - EXPECT_EQ(last_msg_.toc.tow, 446384) - << "incorrect value for last_msg_.toc.tow, expected 446384, is " - << last_msg_.toc.tow; - EXPECT_EQ(last_msg_.toc.wn, 2154) - << "incorrect value for last_msg_.toc.wn, expected 2154, is " - << last_msg_.toc.wn; - EXPECT_LT((last_msg_.w * 100 - -0.98930366296 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -0.98930366296, is " - << last_msg_.w; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_gps_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisGps, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.fit_interval, + greater.common.fit_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.health_bits, greater.common.health_bits); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.code, greater.common.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.sat, greater.common.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.tow, greater.common.toe.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.wn, greater.common.toe.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.ura, greater.common.ura); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.common.valid, greater.common.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.iodc, greater.iodc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.toc.tow, greater.toc.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.toc.wn, greater.toc.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gps_t lesser = info.test_msg; + sbp_msg_ephemeris_gps_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisGps); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_GPS"); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_gps_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_gps_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_gps, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ephemeris_gps, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gps_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisGps, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGPS0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisGps, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGal.cc b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGal.cc index e4395163e3..84e642eae8 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGal.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgEphemerisGal.cc @@ -16,66 +16,308 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgEphemerisGal0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgEphemerisGal0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgEphemerisGal0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgEphemerisGal0() { + assign(test_msg_.af0, -1.7088896129280325e-05); + assign(test_msg_.af1, -8.185452315956353e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.bgd_e1e5a, 2.0954757928848267e-09); + assign(test_msg_.bgd_e1e5b, 2.0954757928848267e-09); + assign(test_msg_.c_ic, -3.166496753692627e-08); + assign(test_msg_.c_is, -3.166496753692627e-08); + assign(test_msg_.c_rc, 265.4375); + assign(test_msg_.c_rs, 10.125); + assign(test_msg_.c_uc, 5.364418029785156e-07); + assign(test_msg_.c_us, 3.993511199951172e-06); + assign(test_msg_.common.fit_interval, 14400); + assign(test_msg_.common.health_bits, 0); + assign(test_msg_.common.sid.code, 14); + assign(test_msg_.common.sid.sat, 27); + assign(test_msg_.common.toe.tow, 448800); + assign(test_msg_.common.toe.wn, 2154); + assign(test_msg_.common.ura, 3.119999885559082); + assign(test_msg_.common.valid, 1); + assign(test_msg_.dn, 3.2262058129932258e-09); + assign(test_msg_.ecc, 0.00017060607206076384); + assign(test_msg_.inc, 0.9777456094977858); + assign(test_msg_.inc_dot, -3.1787038343451465e-10); + assign(test_msg_.iodc, 108); + assign(test_msg_.iode, 108); + assign(test_msg_.m0, -1.8457115744155868); + assign(test_msg_.omega0, 1.16967730598334); + assign(test_msg_.omegadot, -5.757382675240872e-09); + assign(test_msg_.source, 0); + assign(test_msg_.sqrta, 5440.602401733398); + assign(test_msg_.toc.tow, 448800); + assign(test_msg_.toc.wn, 2154); + assign(test_msg_.w, 0.12250912091662625); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_gal_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_gal_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisGal, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_gal_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisGal); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_gal, + sizeof(msg->ephemeris_gal)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_gal_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_gal, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisGal); + info.sender_id = 61568; + info.preamble = 0x55; + info.crc = 0xd047; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 153; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_gal_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_gal_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_gal_t &lesser, + const sbp_msg_ephemeris_gal_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_gal_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_gal_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_gal_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_gal_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGal, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisGal, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisGal, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisGal, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGal0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_gal_t test_msg_{}; + uint8_t encoded_frame_[153 + 8] = { 85, 141, 0, 128, 240, 153, 27, 14, 32, 217, 6, 0, 106, 8, 20, 174, 71, 64, 64, 56, 0, 0, 1, 0, 0, 0, 16, 49, 0, 0, 16, 49, 0, 0, 34, 65, 0, 184, 132, 67, 0, 0, 16, 53, 0, @@ -88,156 +330,506 @@ TEST_F(Test_auto_check_sbp_observation_MsgEphemerisGal0, Test) { 190, 255, 255, 255, 255, 255, 255, 161, 189, 0, 0, 0, 0, 32, 217, 6, 0, 106, 8, 108, 0, 108, 0, 0, 71, 208, }; + uint8_t encoded_payload_[153] = { + 27, 14, 32, 217, 6, 0, 106, 8, 20, 174, 71, 64, 64, 56, + 0, 0, 1, 0, 0, 0, 16, 49, 0, 0, 16, 49, 0, 0, + 34, 65, 0, 184, 132, 67, 0, 0, 16, 53, 0, 0, 134, 54, + 0, 0, 8, 179, 0, 0, 8, 179, 217, 204, 130, 105, 128, 182, + 43, 62, 248, 106, 31, 220, 8, 136, 253, 191, 0, 0, 0, 0, + 151, 92, 38, 63, 0, 0, 0, 55, 154, 64, 181, 64, 56, 38, + 1, 141, 255, 182, 242, 63, 222, 147, 136, 39, 79, 186, 56, 190, + 80, 114, 204, 251, 193, 92, 191, 63, 237, 55, 19, 41, 177, 73, + 239, 63, 49, 65, 189, 240, 8, 216, 245, 189, 255, 255, 255, 255, + 67, 235, 241, 190, 255, 255, 255, 255, 255, 255, 161, 189, 0, 0, + 0, 0, 32, 217, 6, 0, 106, 8, 108, 0, 108, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_gal_encoded_len(&info.test_msg), + info.payload_len); - sbp_msg_ephemeris_gal_t test_msg{}; - test_msg.af0 = -1.7088896129280325e-05; - test_msg.af1 = -8.185452315956353e-12; - test_msg.af2 = 0.0; - test_msg.bgd_e1e5a = 2.0954757928848267e-09; - test_msg.bgd_e1e5b = 2.0954757928848267e-09; - test_msg.c_ic = -3.166496753692627e-08; - test_msg.c_is = -3.166496753692627e-08; - test_msg.c_rc = 265.4375; - test_msg.c_rs = 10.125; - test_msg.c_uc = 5.364418029785156e-07; - test_msg.c_us = 3.993511199951172e-06; - test_msg.common.fit_interval = 14400; - test_msg.common.health_bits = 0; - test_msg.common.sid.code = 14; - test_msg.common.sid.sat = 27; - test_msg.common.toe.tow = 448800; - test_msg.common.toe.wn = 2154; - test_msg.common.ura = 3.119999885559082; - test_msg.common.valid = 1; - test_msg.dn = 3.2262058129932258e-09; - test_msg.ecc = 0.00017060607206076384; - test_msg.inc = 0.9777456094977858; - test_msg.inc_dot = -3.1787038343451465e-10; - test_msg.iodc = 108; - test_msg.iode = 108; - test_msg.m0 = -1.8457115744155868; - test_msg.omega0 = 1.16967730598334; - test_msg.omegadot = -5.757382675240872e-09; - test_msg.source = 0; - test_msg.sqrta = 5440.602401733398; - test_msg.toc.tow = 448800; - test_msg.toc.wn = 2154; - test_msg.w = 0.12250912091662625; - - EXPECT_EQ(send_message(61568, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61568); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -1.70888961293e-05 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -1.70888961293e-05, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -8.18545231596e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -8.18545231596e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.bgd_e1e5a * 100 - 2.09547579288e-09 * 100), 0.05) - << "incorrect value for last_msg_.bgd_e1e5a, expected 2.09547579288e-09, " - "is " - << last_msg_.bgd_e1e5a; - EXPECT_LT((last_msg_.bgd_e1e5b * 100 - 2.09547579288e-09 * 100), 0.05) - << "incorrect value for last_msg_.bgd_e1e5b, expected 2.09547579288e-09, " - "is " - << last_msg_.bgd_e1e5b; - EXPECT_LT((last_msg_.c_ic * 100 - -3.16649675369e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected -3.16649675369e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - -3.16649675369e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected -3.16649675369e-08, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 265.4375 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 265.4375, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - 10.125 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected 10.125, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - 5.36441802979e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected 5.36441802979e-07, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 3.99351119995e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 3.99351119995e-06, is " - << last_msg_.c_us; - EXPECT_EQ(last_msg_.common.fit_interval, 14400) - << "incorrect value for last_msg_.common.fit_interval, expected 14400, " - "is " - << last_msg_.common.fit_interval; - EXPECT_EQ(last_msg_.common.health_bits, 0) - << "incorrect value for last_msg_.common.health_bits, expected 0, is " - << last_msg_.common.health_bits; - EXPECT_EQ(last_msg_.common.sid.code, 14) - << "incorrect value for last_msg_.common.sid.code, expected 14, is " - << last_msg_.common.sid.code; - EXPECT_EQ(last_msg_.common.sid.sat, 27) - << "incorrect value for last_msg_.common.sid.sat, expected 27, is " - << last_msg_.common.sid.sat; - EXPECT_EQ(last_msg_.common.toe.tow, 448800) - << "incorrect value for last_msg_.common.toe.tow, expected 448800, is " - << last_msg_.common.toe.tow; - EXPECT_EQ(last_msg_.common.toe.wn, 2154) - << "incorrect value for last_msg_.common.toe.wn, expected 2154, is " - << last_msg_.common.toe.wn; - EXPECT_LT((last_msg_.common.ura * 100 - 3.11999988556 * 100), 0.05) - << "incorrect value for last_msg_.common.ura, expected 3.11999988556, is " - << last_msg_.common.ura; - EXPECT_EQ(last_msg_.common.valid, 1) - << "incorrect value for last_msg_.common.valid, expected 1, is " - << last_msg_.common.valid; - EXPECT_LT((last_msg_.dn * 100 - 3.22620581299e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 3.22620581299e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.000170606072061 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.000170606072061, is " - << last_msg_.ecc; - EXPECT_LT((last_msg_.inc * 100 - 0.977745609498 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.977745609498, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - -3.17870383435e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected -3.17870383435e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iodc, 108) - << "incorrect value for last_msg_.iodc, expected 108, is " - << last_msg_.iodc; - EXPECT_EQ(last_msg_.iode, 108) - << "incorrect value for last_msg_.iode, expected 108, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - -1.84571157442 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected -1.84571157442, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - 1.16967730598 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected 1.16967730598, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -5.75738267524e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -5.75738267524e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.source, 0) - << "incorrect value for last_msg_.source, expected 0, is " - << last_msg_.source; - EXPECT_LT((last_msg_.sqrta * 100 - 5440.60240173 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5440.60240173, is " - << last_msg_.sqrta; - EXPECT_EQ(last_msg_.toc.tow, 448800) - << "incorrect value for last_msg_.toc.tow, expected 448800, is " - << last_msg_.toc.tow; - EXPECT_EQ(last_msg_.toc.wn, 2154) - << "incorrect value for last_msg_.toc.wn, expected 2154, is " - << last_msg_.toc.wn; - EXPECT_LT((last_msg_.w * 100 - 0.122509120917 * 100), 0.05) - << "incorrect value for last_msg_.w, expected 0.122509120917, is " - << last_msg_.w; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEphemerisGal, &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[153]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_gal_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 153); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 153), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisGal, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 153); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 153), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[153]; + + EXPECT_EQ(sbp_msg_ephemeris_gal_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 153), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[153]; + + for (uint8_t i = 0; i < 153; i++) { + EXPECT_EQ(sbp_msg_ephemeris_gal_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_gal_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 153); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisGal, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 153); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gal_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_gal_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gal_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_gal_decode(&info.encoded_payload[0], i, nullptr, + &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_gal_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisGal, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.bgd_e1e5a, greater.bgd_e1e5a); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.bgd_e1e5b, greater.bgd_e1e5b); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.fit_interval, + greater.common.fit_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.health_bits, greater.common.health_bits); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.code, greater.common.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.sat, greater.common.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.tow, greater.common.toe.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.wn, greater.common.toe.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.ura, greater.common.ura); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.common.valid, greater.common.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.iodc, greater.iodc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.source, greater.source); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.toc.tow, greater.toc.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.toc.wn, greater.toc.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_gal_t lesser = info.test_msg; + sbp_msg_ephemeris_gal_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisGal); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_GAL"); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_gal_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_gal_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_gal, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ephemeris_gal, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[153]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 153); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 153), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_gal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 153); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisGal, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgEphemerisGal0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisGal, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgGloBiases.cc b/c/test/cpp/auto_check_sbp_observation_MsgGloBiases.cc index 7f21221b34..837ea845ff 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgGloBiases.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgGloBiases.cc @@ -16,101 +16,593 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgGloBiases0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgGloBiases0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgGloBiases0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgGloBiases0() { + assign(test_msg_.l1ca_bias, 0); + assign(test_msg_.l1p_bias, 0); + assign(test_msg_.l2ca_bias, 0); + assign(test_msg_.l2p_bias, 0); + assign(test_msg_.mask, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_glo_biases_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_glo_biases_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGloBiases, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_glo_biases_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGloBiases); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->glo_biases, sizeof(msg->glo_biases)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_glo_biases_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.glo_biases, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGloBiases); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0xd34d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 9; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_glo_biases_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_glo_biases_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_glo_biases_t &lesser, + const sbp_msg_glo_biases_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_glo_biases_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_glo_biases_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_glo_biases_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_glo_biases_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGloBiases, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGloBiases, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGloBiases, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGloBiases, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_observation_MsgGloBiases0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_glo_biases_t test_msg_{}; + uint8_t encoded_frame_[9 + 8] = { 85, 117, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 211, }; + uint8_t encoded_payload_[9] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_glo_biases_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGloBiases, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_glo_biases_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGloBiases, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} - sbp_msg_glo_biases_t test_msg{}; - test_msg.l1ca_bias = 0; - test_msg.l1p_bias = 0; - test_msg.l2ca_bias = 0; - test_msg.l2p_bias = 0; - test_msg.mask = 0; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.l1ca_bias, 0) - << "incorrect value for last_msg_.l1ca_bias, expected 0, is " - << last_msg_.l1ca_bias; - EXPECT_EQ(last_msg_.l1p_bias, 0) - << "incorrect value for last_msg_.l1p_bias, expected 0, is " - << last_msg_.l1p_bias; - EXPECT_EQ(last_msg_.l2ca_bias, 0) - << "incorrect value for last_msg_.l2ca_bias, expected 0, is " - << last_msg_.l2ca_bias; - EXPECT_EQ(last_msg_.l2p_bias, 0) - << "incorrect value for last_msg_.l2p_bias, expected 0, is " - << last_msg_.l2p_bias; - EXPECT_EQ(last_msg_.mask, 0) - << "incorrect value for last_msg_.mask, expected 0, is " - << last_msg_.mask; +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + EXPECT_EQ( + sbp_msg_glo_biases_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); } +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + for (uint8_t i = 0; i < 9; i++) { + EXPECT_EQ(sbp_msg_glo_biases_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_glo_biases_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_glo_biases_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGloBiases, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_glo_biases_t msg{}; + + EXPECT_EQ(sbp_msg_glo_biases_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_glo_biases_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_glo_biases_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_glo_biases_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGloBiases, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_glo_biases_t lesser = info.test_msg; + sbp_msg_glo_biases_t greater = info.test_msg; + make_lesser_greater(lesser.l1ca_bias, greater.l1ca_bias); + comparison_tests(lesser, greater); + } + { + sbp_msg_glo_biases_t lesser = info.test_msg; + sbp_msg_glo_biases_t greater = info.test_msg; + make_lesser_greater(lesser.l1p_bias, greater.l1p_bias); + comparison_tests(lesser, greater); + } + { + sbp_msg_glo_biases_t lesser = info.test_msg; + sbp_msg_glo_biases_t greater = info.test_msg; + make_lesser_greater(lesser.l2ca_bias, greater.l2ca_bias); + comparison_tests(lesser, greater); + } + { + sbp_msg_glo_biases_t lesser = info.test_msg; + sbp_msg_glo_biases_t greater = info.test_msg; + make_lesser_greater(lesser.l2p_bias, greater.l2p_bias); + comparison_tests(lesser, greater); + } + { + sbp_msg_glo_biases_t lesser = info.test_msg; + sbp_msg_glo_biases_t greater = info.test_msg; + make_lesser_greater(lesser.mask, greater.mask); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGloBiases); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GLO_BIASES"); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_glo_biases_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_glo_biases_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.glo_biases, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.glo_biases, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_glo_biases_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGloBiases, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgGloBiases0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGloBiases, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgObs.cc b/c/test/cpp/auto_check_sbp_observation_MsgObs.cc index 76f8240897..56c4b1be34 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgObs.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgObs.cc @@ -16,65 +16,424 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgObs0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgObs0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObs0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObs0() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.ns_residual, 0); + assign(test_msg_.header.t.tow, 434293400); + assign(test_msg_.header.t.wn, 2154); + assign(test_msg_.n_obs, 14); + + assign(test_msg_.obs[0].D.f, 172); + assign(test_msg_.obs[0].D.i, -1536); + assign(test_msg_.obs[0].L.f, 146); + assign(test_msg_.obs[0].L.i, 111080057); + assign(test_msg_.obs[0].P, 1056891697); + assign(test_msg_.obs[0].cn0, 182); + assign(test_msg_.obs[0].flags, 15); + assign(test_msg_.obs[0].lock, 10); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.sat, 10); + + assign(test_msg_.obs[1].D.f, 172); + assign(test_msg_.obs[1].D.i, -1197); + assign(test_msg_.obs[1].L.f, 59); + assign(test_msg_.obs[1].L.i, 86555916); + assign(test_msg_.obs[1].P, 1056891934); + assign(test_msg_.obs[1].cn0, 178); + assign(test_msg_.obs[1].flags, 15); + assign(test_msg_.obs[1].lock, 10); + assign(test_msg_.obs[1].sid.code, 1); + assign(test_msg_.obs[1].sid.sat, 10); + + assign(test_msg_.obs[2].D.f, 119); + assign(test_msg_.obs[2].D.i, -3219); + assign(test_msg_.obs[2].L.f, 243); + assign(test_msg_.obs[2].L.i, 127954794); + assign(test_msg_.obs[2].P, 1217449431); + assign(test_msg_.obs[2].cn0, 158); + assign(test_msg_.obs[2].flags, 15); + assign(test_msg_.obs[2].lock, 10); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.sat, 18); + + assign(test_msg_.obs[3].D.f, 27); + assign(test_msg_.obs[3].D.i, -2508); + assign(test_msg_.obs[3].L.f, 12); + assign(test_msg_.obs[3].L.i, 99705055); + assign(test_msg_.obs[3].P, 1217449753); + assign(test_msg_.obs[3].cn0, 125); + assign(test_msg_.obs[3].flags, 11); + assign(test_msg_.obs[3].lock, 9); + assign(test_msg_.obs[3].sid.code, 1); + assign(test_msg_.obs[3].sid.sat, 18); + + assign(test_msg_.obs[4].D.f, 245); + assign(test_msg_.obs[4].D.i, 2829); + assign(test_msg_.obs[4].L.f, 53); + assign(test_msg_.obs[4].L.i, 132024982); + assign(test_msg_.obs[4].P, 1256175650); + assign(test_msg_.obs[4].cn0, 114); + assign(test_msg_.obs[4].flags, 15); + assign(test_msg_.obs[4].lock, 9); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.sat, 22); + + assign(test_msg_.obs[5].D.f, 246); + assign(test_msg_.obs[5].D.i, -2433); + assign(test_msg_.obs[5].L.f, 70); + assign(test_msg_.obs[5].L.i, 121711010); + assign(test_msg_.obs[5].P, 1158041713); + assign(test_msg_.obs[5].cn0, 189); + assign(test_msg_.obs[5].flags, 15); + assign(test_msg_.obs[5].lock, 9); + assign(test_msg_.obs[5].sid.code, 0); + assign(test_msg_.obs[5].sid.sat, 23); + + assign(test_msg_.obs[6].D.f, 231); + assign(test_msg_.obs[6].D.i, -1896); + assign(test_msg_.obs[6].L.f, 221); + assign(test_msg_.obs[6].L.i, 94839765); + assign(test_msg_.obs[6].P, 1158041847); + assign(test_msg_.obs[6].cn0, 158); + assign(test_msg_.obs[6].flags, 11); + assign(test_msg_.obs[6].lock, 9); + assign(test_msg_.obs[6].sid.code, 1); + assign(test_msg_.obs[6].sid.sat, 23); + + assign(test_msg_.obs[7].D.f, 67); + assign(test_msg_.obs[7].D.i, -1997); + assign(test_msg_.obs[7].L.f, 114); + assign(test_msg_.obs[7].L.i, 113998348); + assign(test_msg_.obs[7].P, 1084658184); + assign(test_msg_.obs[7].cn0, 93); + assign(test_msg_.obs[7].flags, 11); + assign(test_msg_.obs[7].lock, 3); + assign(test_msg_.obs[7].sid.code, 0); + assign(test_msg_.obs[7].sid.sat, 27); + + assign(test_msg_.obs[8].D.f, 237); + assign(test_msg_.obs[8].D.i, 3041); + assign(test_msg_.obs[8].L.f, 232); + assign(test_msg_.obs[8].L.i, 133443545); + assign(test_msg_.obs[8].P, 1269673181); + assign(test_msg_.obs[8].cn0, 123); + assign(test_msg_.obs[8].flags, 15); + assign(test_msg_.obs[8].lock, 5); + assign(test_msg_.obs[8].sid.code, 0); + assign(test_msg_.obs[8].sid.sat, 31); + + assign(test_msg_.obs[9].D.f, 62); + assign(test_msg_.obs[9].D.i, 2374); + assign(test_msg_.obs[9].L.f, 40); + assign(test_msg_.obs[9].L.i, 103982040); + assign(test_msg_.obs[9].P, 1269673722); + assign(test_msg_.obs[9].cn0, 120); + assign(test_msg_.obs[9].flags, 11); + assign(test_msg_.obs[9].lock, 3); + assign(test_msg_.obs[9].sid.code, 1); + assign(test_msg_.obs[9].sid.sat, 31); + + assign(test_msg_.obs[10].D.f, 96); + assign(test_msg_.obs[10].D.i, -3446); + assign(test_msg_.obs[10].L.f, 7); + assign(test_msg_.obs[10].L.i, 118217315); + assign(test_msg_.obs[10].P, 1107693703); + assign(test_msg_.obs[10].cn0, 176); + assign(test_msg_.obs[10].flags, 15); + assign(test_msg_.obs[10].lock, 10); + assign(test_msg_.obs[10].sid.code, 3); + assign(test_msg_.obs[10].sid.sat, 2); + + assign(test_msg_.obs[11].D.f, 96); + assign(test_msg_.obs[11].D.i, -1003); + assign(test_msg_.obs[11].L.f, 203); + assign(test_msg_.obs[11].L.i, 104224985); + assign(test_msg_.obs[11].P, 973505172); + assign(test_msg_.obs[11].cn0, 170); + assign(test_msg_.obs[11].flags, 15); + assign(test_msg_.obs[11].lock, 10); + assign(test_msg_.obs[11].sid.code, 3); + assign(test_msg_.obs[11].sid.sat, 3); + + assign(test_msg_.obs[12].D.f, 219); + assign(test_msg_.obs[12].D.i, -3836); + assign(test_msg_.obs[12].L.f, 80); + assign(test_msg_.obs[12].L.i, 114505343); + assign(test_msg_.obs[12].P, 1069903034); + assign(test_msg_.obs[12].cn0, 200); + assign(test_msg_.obs[12].flags, 15); + assign(test_msg_.obs[12].lock, 10); + assign(test_msg_.obs[12].sid.code, 3); + assign(test_msg_.obs[12].sid.sat, 17); + + assign(test_msg_.obs[13].D.f, 182); + assign(test_msg_.obs[13].D.i, -461); + assign(test_msg_.obs[13].L.f, 105); + assign(test_msg_.obs[13].L.i, 102157331); + assign(test_msg_.obs[13].P, 956875687); + assign(test_msg_.obs[13].cn0, 152); + assign(test_msg_.obs[13].flags, 15); + assign(test_msg_.obs[13].lock, 10); + assign(test_msg_.obs[13].sid.code, 3); + assign(test_msg_.obs[13].sid.sat, 18); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, const sbp_msg_obs_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObs, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObs); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs, sizeof(msg->obs)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObs); + info.sender_id = 61569; + info.preamble = 0x55; + info.crc = 0xf8ed; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 249; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_obs_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_t &lesser, + const sbp_msg_obs_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObs, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgObs, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObs, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObs, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgObs0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_t test_msg_{}; + uint8_t encoded_frame_[249 + 8] = { 85, 74, 0, 129, 240, 249, 152, 202, 226, 25, 0, 0, 0, 0, 106, 8, 32, 49, 227, 254, 62, 121, 242, 158, 6, 146, 0, 250, 172, 182, 10, 15, 10, 0, 30, 228, 254, 62, 12, 189, 40, 5, 59, 83, 251, @@ -94,704 +453,1755 @@ TEST_F(Test_auto_check_sbp_observation_MsgObs0, Test) { 8, 57, 19, 204, 22, 6, 105, 51, 254, 182, 152, 10, 15, 18, 3, 237, 248, }; + uint8_t encoded_payload_[249] = { + 152, 202, 226, 25, 0, 0, 0, 0, 106, 8, 32, 49, 227, 254, 62, + 121, 242, 158, 6, 146, 0, 250, 172, 182, 10, 15, 10, 0, 30, 228, + 254, 62, 12, 189, 40, 5, 59, 83, 251, 172, 178, 10, 15, 10, 1, + 215, 205, 144, 72, 106, 111, 160, 7, 243, 109, 243, 119, 158, 10, 15, + 18, 0, 25, 207, 144, 72, 223, 96, 241, 5, 12, 52, 246, 27, 125, + 9, 11, 18, 1, 34, 184, 223, 74, 150, 138, 222, 7, 53, 13, 11, + 245, 114, 9, 15, 22, 0, 113, 80, 6, 69, 162, 41, 65, 7, 70, + 127, 246, 246, 189, 9, 15, 23, 0, 247, 80, 6, 69, 213, 35, 167, + 5, 221, 152, 248, 231, 158, 9, 11, 23, 1, 8, 146, 166, 64, 12, + 122, 203, 6, 114, 51, 248, 67, 93, 3, 11, 27, 0, 221, 172, 173, + 75, 217, 47, 244, 7, 232, 225, 11, 237, 123, 5, 15, 31, 0, 250, + 174, 173, 75, 216, 163, 50, 6, 40, 70, 9, 62, 120, 3, 11, 31, + 1, 135, 16, 6, 66, 99, 218, 11, 7, 7, 138, 242, 96, 176, 10, + 15, 2, 3, 148, 130, 6, 58, 217, 88, 54, 6, 203, 21, 252, 96, + 170, 10, 15, 3, 3, 186, 108, 197, 63, 127, 54, 211, 6, 80, 4, + 241, 219, 200, 10, 15, 17, 3, 167, 195, 8, 57, 19, 204, 22, 6, + 105, 51, 254, 182, 152, 10, 15, 18, 3, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObs0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObs, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[249]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_obs_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 249); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 249), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObs, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 249); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 249), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[249]; + + EXPECT_EQ(sbp_msg_obs_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 249), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObs0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[249]; + + for (uint8_t i = 0; i < 249; i++) { + EXPECT_EQ(sbp_msg_obs_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 249); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObs, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 249); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObs0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_t t{}; + return sbp_msg_obs_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_t t{}; + t.n_obs = 1; + return sbp_msg_obs_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObs, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.ns_residual, + greater.header.t.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].D.f, greater.obs[0].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].D.i, greater.obs[0].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].flags, greater.obs[0].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].D.f, greater.obs[1].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].D.i, greater.obs[1].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].flags, greater.obs[1].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].D.f, greater.obs[2].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].D.i, greater.obs[2].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].flags, greater.obs[2].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].D.f, greater.obs[3].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].D.i, greater.obs[3].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].flags, greater.obs[3].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].D.f, greater.obs[4].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].D.i, greater.obs[4].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].flags, greater.obs[4].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].D.f, greater.obs[5].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].D.i, greater.obs[5].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].flags, greater.obs[5].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.code, greater.obs[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.sat, greater.obs[5].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].D.f, greater.obs[6].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].D.i, greater.obs[6].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.f, greater.obs[6].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.i, greater.obs[6].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].P, greater.obs[6].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].cn0, greater.obs[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].flags, greater.obs[6].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].lock, greater.obs[6].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].sid.code, greater.obs[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].sid.sat, greater.obs[6].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].D.f, greater.obs[7].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].D.i, greater.obs[7].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].L.f, greater.obs[7].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].L.i, greater.obs[7].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].P, greater.obs[7].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].cn0, greater.obs[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].flags, greater.obs[7].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].lock, greater.obs[7].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].sid.code, greater.obs[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].sid.sat, greater.obs[7].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].D.f, greater.obs[8].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].D.i, greater.obs[8].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].L.f, greater.obs[8].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].L.i, greater.obs[8].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].P, greater.obs[8].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].cn0, greater.obs[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].flags, greater.obs[8].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].lock, greater.obs[8].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].sid.code, greater.obs[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].sid.sat, greater.obs[8].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].D.f, greater.obs[9].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].D.i, greater.obs[9].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].L.f, greater.obs[9].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].L.i, greater.obs[9].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].P, greater.obs[9].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].cn0, greater.obs[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].flags, greater.obs[9].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].lock, greater.obs[9].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].sid.code, greater.obs[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].sid.sat, greater.obs[9].sid.sat); + comparison_tests(lesser, greater); + } - sbp_msg_obs_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.ns_residual = 0; - test_msg.header.t.tow = 434293400; - test_msg.header.t.wn = 2154; - test_msg.n_obs = 14; - - test_msg.obs[0].D.f = 172; - test_msg.obs[0].D.i = -1536; - test_msg.obs[0].L.f = 146; - test_msg.obs[0].L.i = 111080057; - test_msg.obs[0].P = 1056891697; - test_msg.obs[0].cn0 = 182; - test_msg.obs[0].flags = 15; - test_msg.obs[0].lock = 10; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.sat = 10; - - test_msg.obs[1].D.f = 172; - test_msg.obs[1].D.i = -1197; - test_msg.obs[1].L.f = 59; - test_msg.obs[1].L.i = 86555916; - test_msg.obs[1].P = 1056891934; - test_msg.obs[1].cn0 = 178; - test_msg.obs[1].flags = 15; - test_msg.obs[1].lock = 10; - test_msg.obs[1].sid.code = 1; - test_msg.obs[1].sid.sat = 10; - - test_msg.obs[2].D.f = 119; - test_msg.obs[2].D.i = -3219; - test_msg.obs[2].L.f = 243; - test_msg.obs[2].L.i = 127954794; - test_msg.obs[2].P = 1217449431; - test_msg.obs[2].cn0 = 158; - test_msg.obs[2].flags = 15; - test_msg.obs[2].lock = 10; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.sat = 18; - - test_msg.obs[3].D.f = 27; - test_msg.obs[3].D.i = -2508; - test_msg.obs[3].L.f = 12; - test_msg.obs[3].L.i = 99705055; - test_msg.obs[3].P = 1217449753; - test_msg.obs[3].cn0 = 125; - test_msg.obs[3].flags = 11; - test_msg.obs[3].lock = 9; - test_msg.obs[3].sid.code = 1; - test_msg.obs[3].sid.sat = 18; - - test_msg.obs[4].D.f = 245; - test_msg.obs[4].D.i = 2829; - test_msg.obs[4].L.f = 53; - test_msg.obs[4].L.i = 132024982; - test_msg.obs[4].P = 1256175650; - test_msg.obs[4].cn0 = 114; - test_msg.obs[4].flags = 15; - test_msg.obs[4].lock = 9; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.sat = 22; - - test_msg.obs[5].D.f = 246; - test_msg.obs[5].D.i = -2433; - test_msg.obs[5].L.f = 70; - test_msg.obs[5].L.i = 121711010; - test_msg.obs[5].P = 1158041713; - test_msg.obs[5].cn0 = 189; - test_msg.obs[5].flags = 15; - test_msg.obs[5].lock = 9; - test_msg.obs[5].sid.code = 0; - test_msg.obs[5].sid.sat = 23; - - test_msg.obs[6].D.f = 231; - test_msg.obs[6].D.i = -1896; - test_msg.obs[6].L.f = 221; - test_msg.obs[6].L.i = 94839765; - test_msg.obs[6].P = 1158041847; - test_msg.obs[6].cn0 = 158; - test_msg.obs[6].flags = 11; - test_msg.obs[6].lock = 9; - test_msg.obs[6].sid.code = 1; - test_msg.obs[6].sid.sat = 23; - - test_msg.obs[7].D.f = 67; - test_msg.obs[7].D.i = -1997; - test_msg.obs[7].L.f = 114; - test_msg.obs[7].L.i = 113998348; - test_msg.obs[7].P = 1084658184; - test_msg.obs[7].cn0 = 93; - test_msg.obs[7].flags = 11; - test_msg.obs[7].lock = 3; - test_msg.obs[7].sid.code = 0; - test_msg.obs[7].sid.sat = 27; - - test_msg.obs[8].D.f = 237; - test_msg.obs[8].D.i = 3041; - test_msg.obs[8].L.f = 232; - test_msg.obs[8].L.i = 133443545; - test_msg.obs[8].P = 1269673181; - test_msg.obs[8].cn0 = 123; - test_msg.obs[8].flags = 15; - test_msg.obs[8].lock = 5; - test_msg.obs[8].sid.code = 0; - test_msg.obs[8].sid.sat = 31; - - test_msg.obs[9].D.f = 62; - test_msg.obs[9].D.i = 2374; - test_msg.obs[9].L.f = 40; - test_msg.obs[9].L.i = 103982040; - test_msg.obs[9].P = 1269673722; - test_msg.obs[9].cn0 = 120; - test_msg.obs[9].flags = 11; - test_msg.obs[9].lock = 3; - test_msg.obs[9].sid.code = 1; - test_msg.obs[9].sid.sat = 31; - - test_msg.obs[10].D.f = 96; - test_msg.obs[10].D.i = -3446; - test_msg.obs[10].L.f = 7; - test_msg.obs[10].L.i = 118217315; - test_msg.obs[10].P = 1107693703; - test_msg.obs[10].cn0 = 176; - test_msg.obs[10].flags = 15; - test_msg.obs[10].lock = 10; - test_msg.obs[10].sid.code = 3; - test_msg.obs[10].sid.sat = 2; - - test_msg.obs[11].D.f = 96; - test_msg.obs[11].D.i = -1003; - test_msg.obs[11].L.f = 203; - test_msg.obs[11].L.i = 104224985; - test_msg.obs[11].P = 973505172; - test_msg.obs[11].cn0 = 170; - test_msg.obs[11].flags = 15; - test_msg.obs[11].lock = 10; - test_msg.obs[11].sid.code = 3; - test_msg.obs[11].sid.sat = 3; - - test_msg.obs[12].D.f = 219; - test_msg.obs[12].D.i = -3836; - test_msg.obs[12].L.f = 80; - test_msg.obs[12].L.i = 114505343; - test_msg.obs[12].P = 1069903034; - test_msg.obs[12].cn0 = 200; - test_msg.obs[12].flags = 15; - test_msg.obs[12].lock = 10; - test_msg.obs[12].sid.code = 3; - test_msg.obs[12].sid.sat = 17; - - test_msg.obs[13].D.f = 182; - test_msg.obs[13].D.i = -461; - test_msg.obs[13].L.f = 105; - test_msg.obs[13].L.i = 102157331; - test_msg.obs[13].P = 956875687; - test_msg.obs[13].cn0 = 152; - test_msg.obs[13].flags = 15; - test_msg.obs[13].lock = 10; - test_msg.obs[13].sid.code = 3; - test_msg.obs[13].sid.sat = 18; - - EXPECT_EQ(send_message(61569, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61569); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.ns_residual, 0) - << "incorrect value for last_msg_.header.t.ns_residual, expected 0, is " - << last_msg_.header.t.ns_residual; - EXPECT_EQ(last_msg_.header.t.tow, 434293400) - << "incorrect value for last_msg_.header.t.tow, expected 434293400, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 2154) - << "incorrect value for last_msg_.header.t.wn, expected 2154, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 14) - << "incorrect value for last_msg_.n_obs, expected 14, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].D.f, 172) - << "incorrect value for last_msg_.obs[0].D.f, expected 172, is " - << last_msg_.obs[0].D.f; - EXPECT_EQ(last_msg_.obs[0].D.i, -1536) - << "incorrect value for last_msg_.obs[0].D.i, expected -1536, is " - << last_msg_.obs[0].D.i; - EXPECT_EQ(last_msg_.obs[0].L.f, 146) - << "incorrect value for last_msg_.obs[0].L.f, expected 146, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 111080057) - << "incorrect value for last_msg_.obs[0].L.i, expected 111080057, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1056891697) - << "incorrect value for last_msg_.obs[0].P, expected 1056891697, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 182) - << "incorrect value for last_msg_.obs[0].cn0, expected 182, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].flags, 15) - << "incorrect value for last_msg_.obs[0].flags, expected 15, is " - << last_msg_.obs[0].flags; - EXPECT_EQ(last_msg_.obs[0].lock, 10) - << "incorrect value for last_msg_.obs[0].lock, expected 10, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 10) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 10, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].D.f, 172) - << "incorrect value for last_msg_.obs[1].D.f, expected 172, is " - << last_msg_.obs[1].D.f; - EXPECT_EQ(last_msg_.obs[1].D.i, -1197) - << "incorrect value for last_msg_.obs[1].D.i, expected -1197, is " - << last_msg_.obs[1].D.i; - EXPECT_EQ(last_msg_.obs[1].L.f, 59) - << "incorrect value for last_msg_.obs[1].L.f, expected 59, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 86555916) - << "incorrect value for last_msg_.obs[1].L.i, expected 86555916, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1056891934) - << "incorrect value for last_msg_.obs[1].P, expected 1056891934, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 178) - << "incorrect value for last_msg_.obs[1].cn0, expected 178, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].flags, 15) - << "incorrect value for last_msg_.obs[1].flags, expected 15, is " - << last_msg_.obs[1].flags; - EXPECT_EQ(last_msg_.obs[1].lock, 10) - << "incorrect value for last_msg_.obs[1].lock, expected 10, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 1) - << "incorrect value for last_msg_.obs[1].sid.code, expected 1, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 10) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 10, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].D.f, 119) - << "incorrect value for last_msg_.obs[2].D.f, expected 119, is " - << last_msg_.obs[2].D.f; - EXPECT_EQ(last_msg_.obs[2].D.i, -3219) - << "incorrect value for last_msg_.obs[2].D.i, expected -3219, is " - << last_msg_.obs[2].D.i; - EXPECT_EQ(last_msg_.obs[2].L.f, 243) - << "incorrect value for last_msg_.obs[2].L.f, expected 243, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 127954794) - << "incorrect value for last_msg_.obs[2].L.i, expected 127954794, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1217449431) - << "incorrect value for last_msg_.obs[2].P, expected 1217449431, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 158) - << "incorrect value for last_msg_.obs[2].cn0, expected 158, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].flags, 15) - << "incorrect value for last_msg_.obs[2].flags, expected 15, is " - << last_msg_.obs[2].flags; - EXPECT_EQ(last_msg_.obs[2].lock, 10) - << "incorrect value for last_msg_.obs[2].lock, expected 10, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 18) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 18, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].D.f, 27) - << "incorrect value for last_msg_.obs[3].D.f, expected 27, is " - << last_msg_.obs[3].D.f; - EXPECT_EQ(last_msg_.obs[3].D.i, -2508) - << "incorrect value for last_msg_.obs[3].D.i, expected -2508, is " - << last_msg_.obs[3].D.i; - EXPECT_EQ(last_msg_.obs[3].L.f, 12) - << "incorrect value for last_msg_.obs[3].L.f, expected 12, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 99705055) - << "incorrect value for last_msg_.obs[3].L.i, expected 99705055, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 1217449753) - << "incorrect value for last_msg_.obs[3].P, expected 1217449753, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 125) - << "incorrect value for last_msg_.obs[3].cn0, expected 125, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].flags, 11) - << "incorrect value for last_msg_.obs[3].flags, expected 11, is " - << last_msg_.obs[3].flags; - EXPECT_EQ(last_msg_.obs[3].lock, 9) - << "incorrect value for last_msg_.obs[3].lock, expected 9, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 1) - << "incorrect value for last_msg_.obs[3].sid.code, expected 1, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 18) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 18, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].D.f, 245) - << "incorrect value for last_msg_.obs[4].D.f, expected 245, is " - << last_msg_.obs[4].D.f; - EXPECT_EQ(last_msg_.obs[4].D.i, 2829) - << "incorrect value for last_msg_.obs[4].D.i, expected 2829, is " - << last_msg_.obs[4].D.i; - EXPECT_EQ(last_msg_.obs[4].L.f, 53) - << "incorrect value for last_msg_.obs[4].L.f, expected 53, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 132024982) - << "incorrect value for last_msg_.obs[4].L.i, expected 132024982, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1256175650) - << "incorrect value for last_msg_.obs[4].P, expected 1256175650, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 114) - << "incorrect value for last_msg_.obs[4].cn0, expected 114, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].flags, 15) - << "incorrect value for last_msg_.obs[4].flags, expected 15, is " - << last_msg_.obs[4].flags; - EXPECT_EQ(last_msg_.obs[4].lock, 9) - << "incorrect value for last_msg_.obs[4].lock, expected 9, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 22) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 22, is " - << last_msg_.obs[4].sid.sat; - EXPECT_EQ(last_msg_.obs[5].D.f, 246) - << "incorrect value for last_msg_.obs[5].D.f, expected 246, is " - << last_msg_.obs[5].D.f; - EXPECT_EQ(last_msg_.obs[5].D.i, -2433) - << "incorrect value for last_msg_.obs[5].D.i, expected -2433, is " - << last_msg_.obs[5].D.i; - EXPECT_EQ(last_msg_.obs[5].L.f, 70) - << "incorrect value for last_msg_.obs[5].L.f, expected 70, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 121711010) - << "incorrect value for last_msg_.obs[5].L.i, expected 121711010, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 1158041713) - << "incorrect value for last_msg_.obs[5].P, expected 1158041713, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 189) - << "incorrect value for last_msg_.obs[5].cn0, expected 189, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].flags, 15) - << "incorrect value for last_msg_.obs[5].flags, expected 15, is " - << last_msg_.obs[5].flags; - EXPECT_EQ(last_msg_.obs[5].lock, 9) - << "incorrect value for last_msg_.obs[5].lock, expected 9, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].sid.code, 0) - << "incorrect value for last_msg_.obs[5].sid.code, expected 0, is " - << last_msg_.obs[5].sid.code; - EXPECT_EQ(last_msg_.obs[5].sid.sat, 23) - << "incorrect value for last_msg_.obs[5].sid.sat, expected 23, is " - << last_msg_.obs[5].sid.sat; - EXPECT_EQ(last_msg_.obs[6].D.f, 231) - << "incorrect value for last_msg_.obs[6].D.f, expected 231, is " - << last_msg_.obs[6].D.f; - EXPECT_EQ(last_msg_.obs[6].D.i, -1896) - << "incorrect value for last_msg_.obs[6].D.i, expected -1896, is " - << last_msg_.obs[6].D.i; - EXPECT_EQ(last_msg_.obs[6].L.f, 221) - << "incorrect value for last_msg_.obs[6].L.f, expected 221, is " - << last_msg_.obs[6].L.f; - EXPECT_EQ(last_msg_.obs[6].L.i, 94839765) - << "incorrect value for last_msg_.obs[6].L.i, expected 94839765, is " - << last_msg_.obs[6].L.i; - EXPECT_EQ(last_msg_.obs[6].P, 1158041847) - << "incorrect value for last_msg_.obs[6].P, expected 1158041847, is " - << last_msg_.obs[6].P; - EXPECT_EQ(last_msg_.obs[6].cn0, 158) - << "incorrect value for last_msg_.obs[6].cn0, expected 158, is " - << last_msg_.obs[6].cn0; - EXPECT_EQ(last_msg_.obs[6].flags, 11) - << "incorrect value for last_msg_.obs[6].flags, expected 11, is " - << last_msg_.obs[6].flags; - EXPECT_EQ(last_msg_.obs[6].lock, 9) - << "incorrect value for last_msg_.obs[6].lock, expected 9, is " - << last_msg_.obs[6].lock; - EXPECT_EQ(last_msg_.obs[6].sid.code, 1) - << "incorrect value for last_msg_.obs[6].sid.code, expected 1, is " - << last_msg_.obs[6].sid.code; - EXPECT_EQ(last_msg_.obs[6].sid.sat, 23) - << "incorrect value for last_msg_.obs[6].sid.sat, expected 23, is " - << last_msg_.obs[6].sid.sat; - EXPECT_EQ(last_msg_.obs[7].D.f, 67) - << "incorrect value for last_msg_.obs[7].D.f, expected 67, is " - << last_msg_.obs[7].D.f; - EXPECT_EQ(last_msg_.obs[7].D.i, -1997) - << "incorrect value for last_msg_.obs[7].D.i, expected -1997, is " - << last_msg_.obs[7].D.i; - EXPECT_EQ(last_msg_.obs[7].L.f, 114) - << "incorrect value for last_msg_.obs[7].L.f, expected 114, is " - << last_msg_.obs[7].L.f; - EXPECT_EQ(last_msg_.obs[7].L.i, 113998348) - << "incorrect value for last_msg_.obs[7].L.i, expected 113998348, is " - << last_msg_.obs[7].L.i; - EXPECT_EQ(last_msg_.obs[7].P, 1084658184) - << "incorrect value for last_msg_.obs[7].P, expected 1084658184, is " - << last_msg_.obs[7].P; - EXPECT_EQ(last_msg_.obs[7].cn0, 93) - << "incorrect value for last_msg_.obs[7].cn0, expected 93, is " - << last_msg_.obs[7].cn0; - EXPECT_EQ(last_msg_.obs[7].flags, 11) - << "incorrect value for last_msg_.obs[7].flags, expected 11, is " - << last_msg_.obs[7].flags; - EXPECT_EQ(last_msg_.obs[7].lock, 3) - << "incorrect value for last_msg_.obs[7].lock, expected 3, is " - << last_msg_.obs[7].lock; - EXPECT_EQ(last_msg_.obs[7].sid.code, 0) - << "incorrect value for last_msg_.obs[7].sid.code, expected 0, is " - << last_msg_.obs[7].sid.code; - EXPECT_EQ(last_msg_.obs[7].sid.sat, 27) - << "incorrect value for last_msg_.obs[7].sid.sat, expected 27, is " - << last_msg_.obs[7].sid.sat; - EXPECT_EQ(last_msg_.obs[8].D.f, 237) - << "incorrect value for last_msg_.obs[8].D.f, expected 237, is " - << last_msg_.obs[8].D.f; - EXPECT_EQ(last_msg_.obs[8].D.i, 3041) - << "incorrect value for last_msg_.obs[8].D.i, expected 3041, is " - << last_msg_.obs[8].D.i; - EXPECT_EQ(last_msg_.obs[8].L.f, 232) - << "incorrect value for last_msg_.obs[8].L.f, expected 232, is " - << last_msg_.obs[8].L.f; - EXPECT_EQ(last_msg_.obs[8].L.i, 133443545) - << "incorrect value for last_msg_.obs[8].L.i, expected 133443545, is " - << last_msg_.obs[8].L.i; - EXPECT_EQ(last_msg_.obs[8].P, 1269673181) - << "incorrect value for last_msg_.obs[8].P, expected 1269673181, is " - << last_msg_.obs[8].P; - EXPECT_EQ(last_msg_.obs[8].cn0, 123) - << "incorrect value for last_msg_.obs[8].cn0, expected 123, is " - << last_msg_.obs[8].cn0; - EXPECT_EQ(last_msg_.obs[8].flags, 15) - << "incorrect value for last_msg_.obs[8].flags, expected 15, is " - << last_msg_.obs[8].flags; - EXPECT_EQ(last_msg_.obs[8].lock, 5) - << "incorrect value for last_msg_.obs[8].lock, expected 5, is " - << last_msg_.obs[8].lock; - EXPECT_EQ(last_msg_.obs[8].sid.code, 0) - << "incorrect value for last_msg_.obs[8].sid.code, expected 0, is " - << last_msg_.obs[8].sid.code; - EXPECT_EQ(last_msg_.obs[8].sid.sat, 31) - << "incorrect value for last_msg_.obs[8].sid.sat, expected 31, is " - << last_msg_.obs[8].sid.sat; - EXPECT_EQ(last_msg_.obs[9].D.f, 62) - << "incorrect value for last_msg_.obs[9].D.f, expected 62, is " - << last_msg_.obs[9].D.f; - EXPECT_EQ(last_msg_.obs[9].D.i, 2374) - << "incorrect value for last_msg_.obs[9].D.i, expected 2374, is " - << last_msg_.obs[9].D.i; - EXPECT_EQ(last_msg_.obs[9].L.f, 40) - << "incorrect value for last_msg_.obs[9].L.f, expected 40, is " - << last_msg_.obs[9].L.f; - EXPECT_EQ(last_msg_.obs[9].L.i, 103982040) - << "incorrect value for last_msg_.obs[9].L.i, expected 103982040, is " - << last_msg_.obs[9].L.i; - EXPECT_EQ(last_msg_.obs[9].P, 1269673722) - << "incorrect value for last_msg_.obs[9].P, expected 1269673722, is " - << last_msg_.obs[9].P; - EXPECT_EQ(last_msg_.obs[9].cn0, 120) - << "incorrect value for last_msg_.obs[9].cn0, expected 120, is " - << last_msg_.obs[9].cn0; - EXPECT_EQ(last_msg_.obs[9].flags, 11) - << "incorrect value for last_msg_.obs[9].flags, expected 11, is " - << last_msg_.obs[9].flags; - EXPECT_EQ(last_msg_.obs[9].lock, 3) - << "incorrect value for last_msg_.obs[9].lock, expected 3, is " - << last_msg_.obs[9].lock; - EXPECT_EQ(last_msg_.obs[9].sid.code, 1) - << "incorrect value for last_msg_.obs[9].sid.code, expected 1, is " - << last_msg_.obs[9].sid.code; - EXPECT_EQ(last_msg_.obs[9].sid.sat, 31) - << "incorrect value for last_msg_.obs[9].sid.sat, expected 31, is " - << last_msg_.obs[9].sid.sat; - EXPECT_EQ(last_msg_.obs[10].D.f, 96) - << "incorrect value for last_msg_.obs[10].D.f, expected 96, is " - << last_msg_.obs[10].D.f; - EXPECT_EQ(last_msg_.obs[10].D.i, -3446) - << "incorrect value for last_msg_.obs[10].D.i, expected -3446, is " - << last_msg_.obs[10].D.i; - EXPECT_EQ(last_msg_.obs[10].L.f, 7) - << "incorrect value for last_msg_.obs[10].L.f, expected 7, is " - << last_msg_.obs[10].L.f; - EXPECT_EQ(last_msg_.obs[10].L.i, 118217315) - << "incorrect value for last_msg_.obs[10].L.i, expected 118217315, is " - << last_msg_.obs[10].L.i; - EXPECT_EQ(last_msg_.obs[10].P, 1107693703) - << "incorrect value for last_msg_.obs[10].P, expected 1107693703, is " - << last_msg_.obs[10].P; - EXPECT_EQ(last_msg_.obs[10].cn0, 176) - << "incorrect value for last_msg_.obs[10].cn0, expected 176, is " - << last_msg_.obs[10].cn0; - EXPECT_EQ(last_msg_.obs[10].flags, 15) - << "incorrect value for last_msg_.obs[10].flags, expected 15, is " - << last_msg_.obs[10].flags; - EXPECT_EQ(last_msg_.obs[10].lock, 10) - << "incorrect value for last_msg_.obs[10].lock, expected 10, is " - << last_msg_.obs[10].lock; - EXPECT_EQ(last_msg_.obs[10].sid.code, 3) - << "incorrect value for last_msg_.obs[10].sid.code, expected 3, is " - << last_msg_.obs[10].sid.code; - EXPECT_EQ(last_msg_.obs[10].sid.sat, 2) - << "incorrect value for last_msg_.obs[10].sid.sat, expected 2, is " - << last_msg_.obs[10].sid.sat; - EXPECT_EQ(last_msg_.obs[11].D.f, 96) - << "incorrect value for last_msg_.obs[11].D.f, expected 96, is " - << last_msg_.obs[11].D.f; - EXPECT_EQ(last_msg_.obs[11].D.i, -1003) - << "incorrect value for last_msg_.obs[11].D.i, expected -1003, is " - << last_msg_.obs[11].D.i; - EXPECT_EQ(last_msg_.obs[11].L.f, 203) - << "incorrect value for last_msg_.obs[11].L.f, expected 203, is " - << last_msg_.obs[11].L.f; - EXPECT_EQ(last_msg_.obs[11].L.i, 104224985) - << "incorrect value for last_msg_.obs[11].L.i, expected 104224985, is " - << last_msg_.obs[11].L.i; - EXPECT_EQ(last_msg_.obs[11].P, 973505172) - << "incorrect value for last_msg_.obs[11].P, expected 973505172, is " - << last_msg_.obs[11].P; - EXPECT_EQ(last_msg_.obs[11].cn0, 170) - << "incorrect value for last_msg_.obs[11].cn0, expected 170, is " - << last_msg_.obs[11].cn0; - EXPECT_EQ(last_msg_.obs[11].flags, 15) - << "incorrect value for last_msg_.obs[11].flags, expected 15, is " - << last_msg_.obs[11].flags; - EXPECT_EQ(last_msg_.obs[11].lock, 10) - << "incorrect value for last_msg_.obs[11].lock, expected 10, is " - << last_msg_.obs[11].lock; - EXPECT_EQ(last_msg_.obs[11].sid.code, 3) - << "incorrect value for last_msg_.obs[11].sid.code, expected 3, is " - << last_msg_.obs[11].sid.code; - EXPECT_EQ(last_msg_.obs[11].sid.sat, 3) - << "incorrect value for last_msg_.obs[11].sid.sat, expected 3, is " - << last_msg_.obs[11].sid.sat; - EXPECT_EQ(last_msg_.obs[12].D.f, 219) - << "incorrect value for last_msg_.obs[12].D.f, expected 219, is " - << last_msg_.obs[12].D.f; - EXPECT_EQ(last_msg_.obs[12].D.i, -3836) - << "incorrect value for last_msg_.obs[12].D.i, expected -3836, is " - << last_msg_.obs[12].D.i; - EXPECT_EQ(last_msg_.obs[12].L.f, 80) - << "incorrect value for last_msg_.obs[12].L.f, expected 80, is " - << last_msg_.obs[12].L.f; - EXPECT_EQ(last_msg_.obs[12].L.i, 114505343) - << "incorrect value for last_msg_.obs[12].L.i, expected 114505343, is " - << last_msg_.obs[12].L.i; - EXPECT_EQ(last_msg_.obs[12].P, 1069903034) - << "incorrect value for last_msg_.obs[12].P, expected 1069903034, is " - << last_msg_.obs[12].P; - EXPECT_EQ(last_msg_.obs[12].cn0, 200) - << "incorrect value for last_msg_.obs[12].cn0, expected 200, is " - << last_msg_.obs[12].cn0; - EXPECT_EQ(last_msg_.obs[12].flags, 15) - << "incorrect value for last_msg_.obs[12].flags, expected 15, is " - << last_msg_.obs[12].flags; - EXPECT_EQ(last_msg_.obs[12].lock, 10) - << "incorrect value for last_msg_.obs[12].lock, expected 10, is " - << last_msg_.obs[12].lock; - EXPECT_EQ(last_msg_.obs[12].sid.code, 3) - << "incorrect value for last_msg_.obs[12].sid.code, expected 3, is " - << last_msg_.obs[12].sid.code; - EXPECT_EQ(last_msg_.obs[12].sid.sat, 17) - << "incorrect value for last_msg_.obs[12].sid.sat, expected 17, is " - << last_msg_.obs[12].sid.sat; - EXPECT_EQ(last_msg_.obs[13].D.f, 182) - << "incorrect value for last_msg_.obs[13].D.f, expected 182, is " - << last_msg_.obs[13].D.f; - EXPECT_EQ(last_msg_.obs[13].D.i, -461) - << "incorrect value for last_msg_.obs[13].D.i, expected -461, is " - << last_msg_.obs[13].D.i; - EXPECT_EQ(last_msg_.obs[13].L.f, 105) - << "incorrect value for last_msg_.obs[13].L.f, expected 105, is " - << last_msg_.obs[13].L.f; - EXPECT_EQ(last_msg_.obs[13].L.i, 102157331) - << "incorrect value for last_msg_.obs[13].L.i, expected 102157331, is " - << last_msg_.obs[13].L.i; - EXPECT_EQ(last_msg_.obs[13].P, 956875687) - << "incorrect value for last_msg_.obs[13].P, expected 956875687, is " - << last_msg_.obs[13].P; - EXPECT_EQ(last_msg_.obs[13].cn0, 152) - << "incorrect value for last_msg_.obs[13].cn0, expected 152, is " - << last_msg_.obs[13].cn0; - EXPECT_EQ(last_msg_.obs[13].flags, 15) - << "incorrect value for last_msg_.obs[13].flags, expected 15, is " - << last_msg_.obs[13].flags; - EXPECT_EQ(last_msg_.obs[13].lock, 10) - << "incorrect value for last_msg_.obs[13].lock, expected 10, is " - << last_msg_.obs[13].lock; - EXPECT_EQ(last_msg_.obs[13].sid.code, 3) - << "incorrect value for last_msg_.obs[13].sid.code, expected 3, is " - << last_msg_.obs[13].sid.code; - EXPECT_EQ(last_msg_.obs[13].sid.sat, 18) - << "incorrect value for last_msg_.obs[13].sid.sat, expected 18, is " - << last_msg_.obs[13].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObs1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].D.f, greater.obs[10].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].D.i, greater.obs[10].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].L.f, greater.obs[10].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].L.i, greater.obs[10].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].P, greater.obs[10].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].cn0, greater.obs[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].flags, greater.obs[10].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].lock, greater.obs[10].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].sid.code, greater.obs[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].sid.sat, greater.obs[10].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].D.f, greater.obs[11].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].D.i, greater.obs[11].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].L.f, greater.obs[11].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].L.i, greater.obs[11].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].P, greater.obs[11].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].cn0, greater.obs[11].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].flags, greater.obs[11].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].lock, greater.obs[11].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].sid.code, greater.obs[11].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].sid.sat, greater.obs[11].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].D.f, greater.obs[12].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].D.i, greater.obs[12].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].L.f, greater.obs[12].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].L.i, greater.obs[12].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].P, greater.obs[12].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].cn0, greater.obs[12].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].flags, greater.obs[12].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].lock, greater.obs[12].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].sid.code, greater.obs[12].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[12].sid.sat, greater.obs[12].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].D.f, greater.obs[13].D.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].D.i, greater.obs[13].D.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].L.f, greater.obs[13].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].L.i, greater.obs[13].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].P, greater.obs[13].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].cn0, greater.obs[13].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].flags, greater.obs[13].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].lock, greater.obs[13].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].sid.code, greater.obs[13].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.obs[13].sid.sat, greater.obs[13].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObs); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[249]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 249); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 249), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 249); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObs, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObs, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObs1 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObs1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObs1() { + assign(test_msg_.header.n_obs, 16); + assign(test_msg_.header.t.ns_residual, 0); + assign(test_msg_.header.t.tow, 434293400); + assign(test_msg_.header.t.wn, 2154); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, const sbp_msg_obs_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObs, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObs); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs, sizeof(msg->obs)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObs); + info.sender_id = 61569; + info.preamble = 0x55; + info.crc = 0x65c9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_obs_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_t &lesser, + const sbp_msg_obs_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObs, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgObs, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObs, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObs, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgObs1, Test) { - uint8_t encoded_frame[] = { + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 74, 0, 129, 240, 11, 152, 202, 226, 25, 0, 0, 0, 0, 106, 8, 16, 201, 101, }; + uint8_t encoded_payload_[11] = { + 152, 202, 226, 25, 0, 0, 0, 0, 106, 8, 16, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObs1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_encoded_len(&info.test_msg), info.payload_len); - sbp_msg_obs_t test_msg{}; - test_msg.header.n_obs = 16; - test_msg.header.t.ns_residual = 0; - test_msg.header.t.tow = 434293400; - test_msg.header.t.wn = 2154; - - EXPECT_EQ(send_message(61569, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61569); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 16) - << "incorrect value for last_msg_.header.n_obs, expected 16, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.ns_residual, 0) - << "incorrect value for last_msg_.header.t.ns_residual, expected 0, is " - << last_msg_.header.t.ns_residual; - EXPECT_EQ(last_msg_.header.t.tow, 434293400) - << "incorrect value for last_msg_.header.t.tow, expected 434293400, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 2154) - << "incorrect value for last_msg_.header.t.wn, expected 2154, is " - << last_msg_.header.t.wn; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObs, &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_observation_MsgObs1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_obs_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObs, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_obs_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObs1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_obs_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObs, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObs1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_obs_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObs, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.ns_residual, + greater.header.t.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_t lesser = info.test_msg; + sbp_msg_obs_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObs); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObs, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObs1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObs, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgObsDepB.cc b/c/test/cpp/auto_check_sbp_observation_MsgObsDepB.cc index 735a47afa6..df78dd79ed 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgObsDepB.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgObsDepB.cc @@ -16,1042 +16,3745 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgObsDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgObsDepB0 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepB0() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 2567800); + assign(test_msg_.header.t.wn, 1787); + assign(test_msg_.n_obs, 6); + + assign(test_msg_.obs[0].L.f, 27); + assign(test_msg_.obs[0].L.i, 117913055); + assign(test_msg_.obs[0].P, 2243669940); + assign(test_msg_.obs[0].cn0, 157); + assign(test_msg_.obs[0].lock, 0); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 202); + + assign(test_msg_.obs[1].L.f, 175); + assign(test_msg_.obs[1].L.i, 129899608); + assign(test_msg_.obs[1].P, 2471857210); + assign(test_msg_.obs[1].cn0, 144); + assign(test_msg_.obs[1].lock, 0); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 203); + + assign(test_msg_.obs[2].L.f, 135); + assign(test_msg_.obs[2].L.i, 122531024); + assign(test_msg_.obs[2].P, 2331544796); + assign(test_msg_.obs[2].cn0, 151); + assign(test_msg_.obs[2].lock, 0); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 208); + + assign(test_msg_.obs[3].L.f, 242); + assign(test_msg_.obs[3].L.i, 119280243); + assign(test_msg_.obs[3].P, 2269692589); + assign(test_msg_.obs[3].cn0, 156); + assign(test_msg_.obs[3].lock, 0); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 212); + + assign(test_msg_.obs[4].L.f, 120); + assign(test_msg_.obs[4].L.i, 109691922); + assign(test_msg_.obs[4].P, 2087293092); + assign(test_msg_.obs[4].cn0, 168); + assign(test_msg_.obs[4].lock, 0); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 217); + + assign(test_msg_.obs[5].L.f, 87); + assign(test_msg_.obs[5].L.i, 123340754); + assign(test_msg_.obs[5].P, 2347034654); + assign(test_msg_.obs[5].cn0, 150); + assign(test_msg_.obs[5].lock, 0); + assign(test_msg_.obs[5].sid.code, 0); + assign(test_msg_.obs[5].sid.reserved, 0); + assign(test_msg_.obs[5].sid.sat, 218); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepB, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_b, sizeof(msg->obs_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_b, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x55a9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 103; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_b_t &lesser, + const sbp_msg_obs_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_b_t test_msg_{}; + uint8_t encoded_frame_[103 + 8] = { + 85, 67, 0, 246, 215, 103, 120, 46, 39, 0, 251, 6, 32, 180, 175, 187, + 133, 223, 53, 7, 7, 27, 157, 0, 0, 202, 0, 0, 0, 58, 140, 85, + 147, 88, 28, 190, 7, 175, 144, 0, 0, 203, 0, 0, 0, 220, 140, 248, + 138, 208, 172, 77, 7, 135, 151, 0, 0, 208, 0, 0, 0, 173, 194, 72, + 135, 115, 18, 28, 7, 242, 156, 0, 0, 212, 0, 0, 0, 164, 144, 105, + 124, 18, 196, 137, 6, 120, 168, 0, 0, 217, 0, 0, 0, 30, 232, 228, + 139, 210, 7, 90, 7, 87, 150, 0, 0, 218, 0, 0, 0, 169, 85, + }; + uint8_t encoded_payload_[103] = { + 120, 46, 39, 0, 251, 6, 32, 180, 175, 187, 133, 223, 53, 7, 7, + 27, 157, 0, 0, 202, 0, 0, 0, 58, 140, 85, 147, 88, 28, 190, + 7, 175, 144, 0, 0, 203, 0, 0, 0, 220, 140, 248, 138, 208, 172, + 77, 7, 135, 151, 0, 0, 208, 0, 0, 0, 173, 194, 72, 135, 115, + 18, 28, 7, 242, 156, 0, 0, 212, 0, 0, 0, 164, 144, 105, 124, + 18, 196, 137, 6, 120, 168, 0, 0, 217, 0, 0, 0, 30, 232, 228, + 139, 210, 7, 90, 7, 87, 150, 0, 0, 218, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_b_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepB, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + EXPECT_EQ( + sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + for (uint8_t i = 0; i < 103; i++) { + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + return sbp_msg_obs_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.code, greater.obs[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.reserved, + greater.obs[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.sat, greater.obs[5].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepB); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepB, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepB, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepB1 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepB1() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 2567800); + assign(test_msg_.header.t.wn, 1787); + assign(test_msg_.n_obs, 3); + + assign(test_msg_.obs[0].L.f, 219); + assign(test_msg_.obs[0].L.i, 120256389); + assign(test_msg_.obs[0].P, 2288371524); + assign(test_msg_.obs[0].cn0, 154); + assign(test_msg_.obs[0].lock, 0); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 220); + + assign(test_msg_.obs[1].L.f, 235); + assign(test_msg_.obs[1].L.i, 117692256); + assign(test_msg_.obs[1].P, 2239434459); + assign(test_msg_.obs[1].cn0, 156); + assign(test_msg_.obs[1].lock, 0); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 222); + + assign(test_msg_.obs[2].L.f, 174); + assign(test_msg_.obs[2].L.i, 107851013); + assign(test_msg_.obs[2].P, 2052171351); + assign(test_msg_.obs[2].cn0, 170); + assign(test_msg_.obs[2].lock, 0); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 225); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepB, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_b, sizeof(msg->obs_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_b, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xe90b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_b_t &lesser, + const sbp_msg_obs_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_b_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 67, 0, 246, 215, 55, 120, 46, 39, 0, 251, 6, 33, 68, 199, 101, + 136, 133, 247, 42, 7, 219, 154, 0, 0, 220, 0, 0, 0, 219, 14, 123, + 133, 96, 215, 3, 7, 235, 156, 0, 0, 222, 0, 0, 0, 87, 166, 81, + 122, 5, 173, 109, 6, 174, 170, 0, 0, 225, 0, 0, 0, 11, 233, + }; + uint8_t encoded_payload_[55] = { + 120, 46, 39, 0, 251, 6, 33, 68, 199, 101, 136, 133, 247, 42, + 7, 219, 154, 0, 0, 220, 0, 0, 0, 219, 14, 123, 133, 96, + 215, 3, 7, 235, 156, 0, 0, 222, 0, 0, 0, 87, 166, 81, + 122, 5, 173, 109, 6, 174, 170, 0, 0, 225, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_b_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepB, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ( + sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + return sbp_msg_obs_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepB); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepB, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepB, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepB2 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepB2() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 2568000); + assign(test_msg_.header.t.wn, 1787); + assign(test_msg_.n_obs, 6); + + assign(test_msg_.obs[0].L.f, 94); + assign(test_msg_.obs[0].L.i, 117912556); + assign(test_msg_.obs[0].P, 2243658852); + assign(test_msg_.obs[0].cn0, 156); + assign(test_msg_.obs[0].lock, 0); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 202); + + assign(test_msg_.obs[1].L.f, 40); + assign(test_msg_.obs[1].L.i, 129900210); + assign(test_msg_.obs[1].P, 2471868513); + assign(test_msg_.obs[1].cn0, 140); + assign(test_msg_.obs[1].lock, 0); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 203); + + assign(test_msg_.obs[2].L.f, 2); + assign(test_msg_.obs[2].L.i, 122530650); + assign(test_msg_.obs[2].P, 2331537287); + assign(test_msg_.obs[2].cn0, 150); + assign(test_msg_.obs[2].lock, 0); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 208); + + assign(test_msg_.obs[3].L.f, 241); + assign(test_msg_.obs[3].L.i, 119280830); + assign(test_msg_.obs[3].P, 2269703860); + assign(test_msg_.obs[3].cn0, 155); + assign(test_msg_.obs[3].lock, 0); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 212); + + assign(test_msg_.obs[4].L.f, 153); + assign(test_msg_.obs[4].L.i, 109691996); + assign(test_msg_.obs[4].P, 2087295247); + assign(test_msg_.obs[4].cn0, 168); + assign(test_msg_.obs[4].lock, 0); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 217); + + assign(test_msg_.obs[5].L.f, 41); + assign(test_msg_.obs[5].L.i, 123340176); + assign(test_msg_.obs[5].P, 2347022641); + assign(test_msg_.obs[5].cn0, 150); + assign(test_msg_.obs[5].lock, 0); + assign(test_msg_.obs[5].sid.code, 0); + assign(test_msg_.obs[5].sid.reserved, 0); + assign(test_msg_.obs[5].sid.sat, 218); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepB, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_b, sizeof(msg->obs_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_b, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x62f1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 103; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_b_t &lesser, + const sbp_msg_obs_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_b_t test_msg_{}; + uint8_t encoded_frame_[103 + 8] = { + 85, 67, 0, 246, 215, 103, 64, 47, 39, 0, 251, 6, 32, 100, 132, 187, + 133, 236, 51, 7, 7, 94, 156, 0, 0, 202, 0, 0, 0, 97, 184, 85, + 147, 178, 30, 190, 7, 40, 140, 0, 0, 203, 0, 0, 0, 135, 111, 248, + 138, 90, 171, 77, 7, 2, 150, 0, 0, 208, 0, 0, 0, 180, 238, 72, + 135, 190, 20, 28, 7, 241, 155, 0, 0, 212, 0, 0, 0, 15, 153, 105, + 124, 92, 196, 137, 6, 153, 168, 0, 0, 217, 0, 0, 0, 49, 185, 228, + 139, 144, 5, 90, 7, 41, 150, 0, 0, 218, 0, 0, 0, 241, 98, + }; + uint8_t encoded_payload_[103] = { + 64, 47, 39, 0, 251, 6, 32, 100, 132, 187, 133, 236, 51, 7, 7, + 94, 156, 0, 0, 202, 0, 0, 0, 97, 184, 85, 147, 178, 30, 190, + 7, 40, 140, 0, 0, 203, 0, 0, 0, 135, 111, 248, 138, 90, 171, + 77, 7, 2, 150, 0, 0, 208, 0, 0, 0, 180, 238, 72, 135, 190, + 20, 28, 7, 241, 155, 0, 0, 212, 0, 0, 0, 15, 153, 105, 124, + 92, 196, 137, 6, 153, 168, 0, 0, 217, 0, 0, 0, 49, 185, 228, + 139, 144, 5, 90, 7, 41, 150, 0, 0, 218, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_b_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepB, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + EXPECT_EQ( + sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + for (uint8_t i = 0; i < 103; i++) { + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + return sbp_msg_obs_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.code, greater.obs[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.reserved, + greater.obs[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.sat, greater.obs[5].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepB); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepB, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepB, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepB3 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObsDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObsDepB3() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 2568000); + assign(test_msg_.header.t.wn, 1787); + assign(test_msg_.n_obs, 3); + + assign(test_msg_.obs[0].L.f, 20); + assign(test_msg_.obs[0].L.i, 120255759); + assign(test_msg_.obs[0].P, 2288358634); + assign(test_msg_.obs[0].cn0, 154); + assign(test_msg_.obs[0].lock, 0); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 220); + + assign(test_msg_.obs[1].L.f, 38); + assign(test_msg_.obs[1].L.i, 117691920); + assign(test_msg_.obs[1].P, 2239428560); + assign(test_msg_.obs[1].cn0, 156); + assign(test_msg_.obs[1].lock, 0); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 222); + + assign(test_msg_.obs[2].L.f, 7); + assign(test_msg_.obs[2].L.i, 107850774); + assign(test_msg_.obs[2].P, 2052167183); + assign(test_msg_.obs[2].cn0, 172); + assign(test_msg_.obs[2].lock, 0); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 225); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepB, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_b, sizeof(msg->obs_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_b, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xdc9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_b_t &lesser, + const sbp_msg_obs_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_b_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 67, 0, 246, 215, 55, 64, 47, 39, 0, 251, 6, 33, 234, 148, 101, + 136, 15, 245, 42, 7, 20, 154, 0, 0, 220, 0, 0, 0, 208, 247, 122, + 133, 16, 214, 3, 7, 38, 156, 0, 0, 222, 0, 0, 0, 15, 150, 81, + 122, 22, 172, 109, 6, 7, 172, 0, 0, 225, 0, 0, 0, 201, 13, + }; + uint8_t encoded_payload_[55] = { + 64, 47, 39, 0, 251, 6, 33, 234, 148, 101, 136, 15, 245, 42, + 7, 20, 154, 0, 0, 220, 0, 0, 0, 208, 247, 122, 133, 16, + 214, 3, 7, 38, 156, 0, 0, 222, 0, 0, 0, 15, 150, 81, + 122, 22, 172, 109, 6, 7, 172, 0, 0, 225, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_b_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepB, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ( + sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + return sbp_msg_obs_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepB); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_observation_MsgObsDepB0, Test) { - uint8_t encoded_frame[] = { - 85, 67, 0, 246, 215, 103, 120, 46, 39, 0, 251, 6, 32, 180, 175, 187, - 133, 223, 53, 7, 7, 27, 157, 0, 0, 202, 0, 0, 0, 58, 140, 85, - 147, 88, 28, 190, 7, 175, 144, 0, 0, 203, 0, 0, 0, 220, 140, 248, - 138, 208, 172, 77, 7, 135, 151, 0, 0, 208, 0, 0, 0, 173, 194, 72, - 135, 115, 18, 28, 7, 242, 156, 0, 0, 212, 0, 0, 0, 164, 144, 105, - 124, 18, 196, 137, 6, 120, 168, 0, 0, 217, 0, 0, 0, 30, 232, 228, - 139, 210, 7, 90, 7, 87, 150, 0, 0, 218, 0, 0, 0, 169, 85, - }; +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); - sbp_msg_obs_dep_b_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 2567800; - test_msg.header.t.wn = 1787; - test_msg.n_obs = 6; - - test_msg.obs[0].L.f = 27; - test_msg.obs[0].L.i = 117913055; - test_msg.obs[0].P = 2243669940; - test_msg.obs[0].cn0 = 157; - test_msg.obs[0].lock = 0; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 202; - - test_msg.obs[1].L.f = 175; - test_msg.obs[1].L.i = 129899608; - test_msg.obs[1].P = 2471857210; - test_msg.obs[1].cn0 = 144; - test_msg.obs[1].lock = 0; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 203; - - test_msg.obs[2].L.f = 135; - test_msg.obs[2].L.i = 122531024; - test_msg.obs[2].P = 2331544796; - test_msg.obs[2].cn0 = 151; - test_msg.obs[2].lock = 0; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 208; - - test_msg.obs[3].L.f = 242; - test_msg.obs[3].L.i = 119280243; - test_msg.obs[3].P = 2269692589; - test_msg.obs[3].cn0 = 156; - test_msg.obs[3].lock = 0; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 212; - - test_msg.obs[4].L.f = 120; - test_msg.obs[4].L.i = 109691922; - test_msg.obs[4].P = 2087293092; - test_msg.obs[4].cn0 = 168; - test_msg.obs[4].lock = 0; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 217; - - test_msg.obs[5].L.f = 87; - test_msg.obs[5].L.i = 123340754; - test_msg.obs[5].P = 2347034654; - test_msg.obs[5].cn0 = 150; - test_msg.obs[5].lock = 0; - test_msg.obs[5].sid.code = 0; - test_msg.obs[5].sid.reserved = 0; - test_msg.obs[5].sid.sat = 218; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 2567800) - << "incorrect value for last_msg_.header.t.tow, expected 2567800, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1787) - << "incorrect value for last_msg_.header.t.wn, expected 1787, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 6) - << "incorrect value for last_msg_.n_obs, expected 6, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 27) - << "incorrect value for last_msg_.obs[0].L.f, expected 27, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 117913055) - << "incorrect value for last_msg_.obs[0].L.i, expected 117913055, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2243669940) - << "incorrect value for last_msg_.obs[0].P, expected 2243669940, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 157) - << "incorrect value for last_msg_.obs[0].cn0, expected 157, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 0) - << "incorrect value for last_msg_.obs[0].lock, expected 0, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 202) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 202, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 175) - << "incorrect value for last_msg_.obs[1].L.f, expected 175, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 129899608) - << "incorrect value for last_msg_.obs[1].L.i, expected 129899608, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2471857210) - << "incorrect value for last_msg_.obs[1].P, expected 2471857210, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 144) - << "incorrect value for last_msg_.obs[1].cn0, expected 144, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 0) - << "incorrect value for last_msg_.obs[1].lock, expected 0, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 203) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 203, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 135) - << "incorrect value for last_msg_.obs[2].L.f, expected 135, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 122531024) - << "incorrect value for last_msg_.obs[2].L.i, expected 122531024, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2331544796) - << "incorrect value for last_msg_.obs[2].P, expected 2331544796, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 151) - << "incorrect value for last_msg_.obs[2].cn0, expected 151, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 0) - << "incorrect value for last_msg_.obs[2].lock, expected 0, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 208) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 208, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 242) - << "incorrect value for last_msg_.obs[3].L.f, expected 242, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 119280243) - << "incorrect value for last_msg_.obs[3].L.i, expected 119280243, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2269692589) - << "incorrect value for last_msg_.obs[3].P, expected 2269692589, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 156) - << "incorrect value for last_msg_.obs[3].cn0, expected 156, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 0) - << "incorrect value for last_msg_.obs[3].lock, expected 0, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 212) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 212, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 120) - << "incorrect value for last_msg_.obs[4].L.f, expected 120, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 109691922) - << "incorrect value for last_msg_.obs[4].L.i, expected 109691922, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 2087293092) - << "incorrect value for last_msg_.obs[4].P, expected 2087293092, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 168) - << "incorrect value for last_msg_.obs[4].cn0, expected 168, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 0) - << "incorrect value for last_msg_.obs[4].lock, expected 0, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 217) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 217, is " - << last_msg_.obs[4].sid.sat; - EXPECT_EQ(last_msg_.obs[5].L.f, 87) - << "incorrect value for last_msg_.obs[5].L.f, expected 87, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 123340754) - << "incorrect value for last_msg_.obs[5].L.i, expected 123340754, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 2347034654) - << "incorrect value for last_msg_.obs[5].P, expected 2347034654, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 150) - << "incorrect value for last_msg_.obs[5].cn0, expected 150, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].lock, 0) - << "incorrect value for last_msg_.obs[5].lock, expected 0, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].sid.code, 0) - << "incorrect value for last_msg_.obs[5].sid.code, expected 0, is " - << last_msg_.obs[5].sid.code; - EXPECT_EQ(last_msg_.obs[5].sid.reserved, 0) - << "incorrect value for last_msg_.obs[5].sid.reserved, expected 0, is " - << last_msg_.obs[5].sid.reserved; - EXPECT_EQ(last_msg_.obs[5].sid.sat, 218) - << "incorrect value for last_msg_.obs[5].sid.sat, expected 218, is " - << last_msg_.obs[5].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepB1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + state.process_message(info.sender_id, SbpMsgObsDepB, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepB, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepB4 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObsDepB1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObsDepB4() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 2568200); + assign(test_msg_.header.t.wn, 1787); + assign(test_msg_.n_obs, 6); + + assign(test_msg_.obs[0].L.f, 165); + assign(test_msg_.obs[0].L.i, 117912057); + assign(test_msg_.obs[0].P, 2243649790); + assign(test_msg_.obs[0].cn0, 156); + assign(test_msg_.obs[0].lock, 0); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 202); + + assign(test_msg_.obs[1].L.f, 106); + assign(test_msg_.obs[1].L.i, 129900811); + assign(test_msg_.obs[1].P, 2471880049); + assign(test_msg_.obs[1].cn0, 143); + assign(test_msg_.obs[1].lock, 0); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 203); + + assign(test_msg_.obs[2].L.f, 159); + assign(test_msg_.obs[2].L.i, 122530275); + assign(test_msg_.obs[2].P, 2331530678); + assign(test_msg_.obs[2].cn0, 150); + assign(test_msg_.obs[2].lock, 0); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 208); + + assign(test_msg_.obs[3].L.f, 7); + assign(test_msg_.obs[3].L.i, 119281418); + assign(test_msg_.obs[3].P, 2269714449); + assign(test_msg_.obs[3].cn0, 156); + assign(test_msg_.obs[3].lock, 0); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 212); + + assign(test_msg_.obs[4].L.f, 186); + assign(test_msg_.obs[4].L.i, 109692070); + assign(test_msg_.obs[4].P, 2087295852); + assign(test_msg_.obs[4].cn0, 170); + assign(test_msg_.obs[4].lock, 0); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 217); + + assign(test_msg_.obs[5].L.f, 236); + assign(test_msg_.obs[5].L.i, 123339597); + assign(test_msg_.obs[5].P, 2347011798); + assign(test_msg_.obs[5].cn0, 151); + assign(test_msg_.obs[5].lock, 0); + assign(test_msg_.obs[5].sid.code, 0); + assign(test_msg_.obs[5].sid.reserved, 0); + assign(test_msg_.obs[5].sid.sat, 218); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_observation_MsgObsDepB1, Test) { - uint8_t encoded_frame[] = { - 85, 67, 0, 246, 215, 55, 120, 46, 39, 0, 251, 6, 33, 68, 199, 101, - 136, 133, 247, 42, 7, 219, 154, 0, 0, 220, 0, 0, 0, 219, 14, 123, - 133, 96, 215, 3, 7, 235, 156, 0, 0, 222, 0, 0, 0, 87, 166, 81, - 122, 5, 173, 109, 6, 174, 170, 0, 0, 225, 0, 0, 0, 11, 233, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_obs_dep_b_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 2567800; - test_msg.header.t.wn = 1787; - test_msg.n_obs = 3; - - test_msg.obs[0].L.f = 219; - test_msg.obs[0].L.i = 120256389; - test_msg.obs[0].P = 2288371524; - test_msg.obs[0].cn0 = 154; - test_msg.obs[0].lock = 0; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 220; - - test_msg.obs[1].L.f = 235; - test_msg.obs[1].L.i = 117692256; - test_msg.obs[1].P = 2239434459; - test_msg.obs[1].cn0 = 156; - test_msg.obs[1].lock = 0; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 222; - - test_msg.obs[2].L.f = 174; - test_msg.obs[2].L.i = 107851013; - test_msg.obs[2].P = 2052171351; - test_msg.obs[2].cn0 = 170; - test_msg.obs[2].lock = 0; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 225; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 2567800) - << "incorrect value for last_msg_.header.t.tow, expected 2567800, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1787) - << "incorrect value for last_msg_.header.t.wn, expected 1787, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 3) - << "incorrect value for last_msg_.n_obs, expected 3, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 219) - << "incorrect value for last_msg_.obs[0].L.f, expected 219, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 120256389) - << "incorrect value for last_msg_.obs[0].L.i, expected 120256389, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2288371524) - << "incorrect value for last_msg_.obs[0].P, expected 2288371524, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 154) - << "incorrect value for last_msg_.obs[0].cn0, expected 154, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 0) - << "incorrect value for last_msg_.obs[0].lock, expected 0, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 220) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 220, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 235) - << "incorrect value for last_msg_.obs[1].L.f, expected 235, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 117692256) - << "incorrect value for last_msg_.obs[1].L.i, expected 117692256, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2239434459) - << "incorrect value for last_msg_.obs[1].P, expected 2239434459, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 156) - << "incorrect value for last_msg_.obs[1].cn0, expected 156, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 0) - << "incorrect value for last_msg_.obs[1].lock, expected 0, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 222) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 222, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 174) - << "incorrect value for last_msg_.obs[2].L.f, expected 174, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 107851013) - << "incorrect value for last_msg_.obs[2].L.i, expected 107851013, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2052171351) - << "incorrect value for last_msg_.obs[2].P, expected 2052171351, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 170) - << "incorrect value for last_msg_.obs[2].cn0, expected 170, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 0) - << "incorrect value for last_msg_.obs[2].lock, expected 0, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 225) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 225, is " - << last_msg_.obs[2].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepB2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepB2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_observation_MsgObsDepB2, Test) { - uint8_t encoded_frame[] = { - 85, 67, 0, 246, 215, 103, 64, 47, 39, 0, 251, 6, 32, 100, 132, 187, - 133, 236, 51, 7, 7, 94, 156, 0, 0, 202, 0, 0, 0, 97, 184, 85, - 147, 178, 30, 190, 7, 40, 140, 0, 0, 203, 0, 0, 0, 135, 111, 248, - 138, 90, 171, 77, 7, 2, 150, 0, 0, 208, 0, 0, 0, 180, 238, 72, - 135, 190, 20, 28, 7, 241, 155, 0, 0, 212, 0, 0, 0, 15, 153, 105, - 124, 92, 196, 137, 6, 153, 168, 0, 0, 217, 0, 0, 0, 49, 185, 228, - 139, 144, 5, 90, 7, 41, 150, 0, 0, 218, 0, 0, 0, 241, 98, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_obs_dep_b_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 2568000; - test_msg.header.t.wn = 1787; - test_msg.n_obs = 6; - - test_msg.obs[0].L.f = 94; - test_msg.obs[0].L.i = 117912556; - test_msg.obs[0].P = 2243658852; - test_msg.obs[0].cn0 = 156; - test_msg.obs[0].lock = 0; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 202; - - test_msg.obs[1].L.f = 40; - test_msg.obs[1].L.i = 129900210; - test_msg.obs[1].P = 2471868513; - test_msg.obs[1].cn0 = 140; - test_msg.obs[1].lock = 0; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 203; - - test_msg.obs[2].L.f = 2; - test_msg.obs[2].L.i = 122530650; - test_msg.obs[2].P = 2331537287; - test_msg.obs[2].cn0 = 150; - test_msg.obs[2].lock = 0; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 208; - - test_msg.obs[3].L.f = 241; - test_msg.obs[3].L.i = 119280830; - test_msg.obs[3].P = 2269703860; - test_msg.obs[3].cn0 = 155; - test_msg.obs[3].lock = 0; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 212; - - test_msg.obs[4].L.f = 153; - test_msg.obs[4].L.i = 109691996; - test_msg.obs[4].P = 2087295247; - test_msg.obs[4].cn0 = 168; - test_msg.obs[4].lock = 0; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 217; - - test_msg.obs[5].L.f = 41; - test_msg.obs[5].L.i = 123340176; - test_msg.obs[5].P = 2347022641; - test_msg.obs[5].cn0 = 150; - test_msg.obs[5].lock = 0; - test_msg.obs[5].sid.code = 0; - test_msg.obs[5].sid.reserved = 0; - test_msg.obs[5].sid.sat = 218; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 2568000) - << "incorrect value for last_msg_.header.t.tow, expected 2568000, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1787) - << "incorrect value for last_msg_.header.t.wn, expected 1787, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 6) - << "incorrect value for last_msg_.n_obs, expected 6, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 94) - << "incorrect value for last_msg_.obs[0].L.f, expected 94, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 117912556) - << "incorrect value for last_msg_.obs[0].L.i, expected 117912556, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2243658852) - << "incorrect value for last_msg_.obs[0].P, expected 2243658852, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 156) - << "incorrect value for last_msg_.obs[0].cn0, expected 156, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 0) - << "incorrect value for last_msg_.obs[0].lock, expected 0, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 202) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 202, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 40) - << "incorrect value for last_msg_.obs[1].L.f, expected 40, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 129900210) - << "incorrect value for last_msg_.obs[1].L.i, expected 129900210, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2471868513) - << "incorrect value for last_msg_.obs[1].P, expected 2471868513, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 140) - << "incorrect value for last_msg_.obs[1].cn0, expected 140, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 0) - << "incorrect value for last_msg_.obs[1].lock, expected 0, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 203) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 203, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 2) - << "incorrect value for last_msg_.obs[2].L.f, expected 2, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 122530650) - << "incorrect value for last_msg_.obs[2].L.i, expected 122530650, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2331537287) - << "incorrect value for last_msg_.obs[2].P, expected 2331537287, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 150) - << "incorrect value for last_msg_.obs[2].cn0, expected 150, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 0) - << "incorrect value for last_msg_.obs[2].lock, expected 0, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 208) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 208, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 241) - << "incorrect value for last_msg_.obs[3].L.f, expected 241, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 119280830) - << "incorrect value for last_msg_.obs[3].L.i, expected 119280830, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2269703860) - << "incorrect value for last_msg_.obs[3].P, expected 2269703860, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 155) - << "incorrect value for last_msg_.obs[3].cn0, expected 155, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 0) - << "incorrect value for last_msg_.obs[3].lock, expected 0, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 212) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 212, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 153) - << "incorrect value for last_msg_.obs[4].L.f, expected 153, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 109691996) - << "incorrect value for last_msg_.obs[4].L.i, expected 109691996, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 2087295247) - << "incorrect value for last_msg_.obs[4].P, expected 2087295247, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 168) - << "incorrect value for last_msg_.obs[4].cn0, expected 168, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 0) - << "incorrect value for last_msg_.obs[4].lock, expected 0, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 217) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 217, is " - << last_msg_.obs[4].sid.sat; - EXPECT_EQ(last_msg_.obs[5].L.f, 41) - << "incorrect value for last_msg_.obs[5].L.f, expected 41, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 123340176) - << "incorrect value for last_msg_.obs[5].L.i, expected 123340176, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 2347022641) - << "incorrect value for last_msg_.obs[5].P, expected 2347022641, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 150) - << "incorrect value for last_msg_.obs[5].cn0, expected 150, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].lock, 0) - << "incorrect value for last_msg_.obs[5].lock, expected 0, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].sid.code, 0) - << "incorrect value for last_msg_.obs[5].sid.code, expected 0, is " - << last_msg_.obs[5].sid.code; - EXPECT_EQ(last_msg_.obs[5].sid.reserved, 0) - << "incorrect value for last_msg_.obs[5].sid.reserved, expected 0, is " - << last_msg_.obs[5].sid.reserved; - EXPECT_EQ(last_msg_.obs[5].sid.sat, 218) - << "incorrect value for last_msg_.obs[5].sid.sat, expected 218, is " - << last_msg_.obs[5].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepB3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepB3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; -TEST_F(Test_auto_check_sbp_observation_MsgObsDepB3, Test) { - uint8_t encoded_frame[] = { - 85, 67, 0, 246, 215, 55, 64, 47, 39, 0, 251, 6, 33, 234, 148, 101, - 136, 15, 245, 42, 7, 20, 154, 0, 0, 220, 0, 0, 0, 208, 247, 122, - 133, 16, 214, 3, 7, 38, 156, 0, 0, 222, 0, 0, 0, 15, 150, 81, - 122, 22, 172, 109, 6, 7, 172, 0, 0, 225, 0, 0, 0, 201, 13, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_obs_dep_b_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 2568000; - test_msg.header.t.wn = 1787; - test_msg.n_obs = 3; - - test_msg.obs[0].L.f = 20; - test_msg.obs[0].L.i = 120255759; - test_msg.obs[0].P = 2288358634; - test_msg.obs[0].cn0 = 154; - test_msg.obs[0].lock = 0; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 220; - - test_msg.obs[1].L.f = 38; - test_msg.obs[1].L.i = 117691920; - test_msg.obs[1].P = 2239428560; - test_msg.obs[1].cn0 = 156; - test_msg.obs[1].lock = 0; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 222; - - test_msg.obs[2].L.f = 7; - test_msg.obs[2].L.i = 107850774; - test_msg.obs[2].P = 2052167183; - test_msg.obs[2].cn0 = 172; - test_msg.obs[2].lock = 0; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 225; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 2568000) - << "incorrect value for last_msg_.header.t.tow, expected 2568000, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1787) - << "incorrect value for last_msg_.header.t.wn, expected 1787, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 3) - << "incorrect value for last_msg_.n_obs, expected 3, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 20) - << "incorrect value for last_msg_.obs[0].L.f, expected 20, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 120255759) - << "incorrect value for last_msg_.obs[0].L.i, expected 120255759, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2288358634) - << "incorrect value for last_msg_.obs[0].P, expected 2288358634, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 154) - << "incorrect value for last_msg_.obs[0].cn0, expected 154, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 0) - << "incorrect value for last_msg_.obs[0].lock, expected 0, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 220) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 220, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 38) - << "incorrect value for last_msg_.obs[1].L.f, expected 38, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 117691920) - << "incorrect value for last_msg_.obs[1].L.i, expected 117691920, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2239428560) - << "incorrect value for last_msg_.obs[1].P, expected 2239428560, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 156) - << "incorrect value for last_msg_.obs[1].cn0, expected 156, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 0) - << "incorrect value for last_msg_.obs[1].lock, expected 0, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 222) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 222, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 7) - << "incorrect value for last_msg_.obs[2].L.f, expected 7, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 107850774) - << "incorrect value for last_msg_.obs[2].L.i, expected 107850774, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2052167183) - << "incorrect value for last_msg_.obs[2].P, expected 2052167183, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 172) - << "incorrect value for last_msg_.obs[2].cn0, expected 172, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 0) - << "incorrect value for last_msg_.obs[2].lock, expected 0, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 225) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 225, is " - << last_msg_.obs[2].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepB4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepB4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepB, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_b, sizeof(msg->obs_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_b, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x763b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 103; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_dep_b_t &lesser, + const sbp_msg_obs_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_observation_MsgObsDepB4, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_obs_dep_b_t test_msg_{}; + uint8_t encoded_frame_[103 + 8] = { 85, 67, 0, 246, 215, 103, 8, 48, 39, 0, 251, 6, 32, 254, 96, 187, 133, 249, 49, 7, 7, 165, 156, 0, 0, 202, 0, 0, 0, 113, 229, 85, 147, 11, 33, 190, 7, 106, 143, 0, 0, 203, 0, 0, 0, 182, 85, 248, @@ -1060,233 +3763,631 @@ TEST_F(Test_auto_check_sbp_observation_MsgObsDepB4, Test) { 124, 166, 196, 137, 6, 186, 170, 0, 0, 217, 0, 0, 0, 214, 142, 228, 139, 77, 3, 90, 7, 236, 151, 0, 0, 218, 0, 0, 0, 59, 118, }; + uint8_t encoded_payload_[103] = { + 8, 48, 39, 0, 251, 6, 32, 254, 96, 187, 133, 249, 49, 7, 7, + 165, 156, 0, 0, 202, 0, 0, 0, 113, 229, 85, 147, 11, 33, 190, + 7, 106, 143, 0, 0, 203, 0, 0, 0, 182, 85, 248, 138, 227, 169, + 77, 7, 159, 150, 0, 0, 208, 0, 0, 0, 17, 24, 73, 135, 10, + 23, 28, 7, 7, 156, 0, 0, 212, 0, 0, 0, 108, 155, 105, 124, + 166, 196, 137, 6, 186, 170, 0, 0, 217, 0, 0, 0, 214, 142, 228, + 139, 77, 3, 90, 7, 236, 151, 0, 0, 218, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_b_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepB, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + EXPECT_EQ( + sbp_msg_obs_dep_b_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + + for (uint8_t i = 0; i < 103; i++) { + EXPECT_EQ(sbp_msg_obs_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} - sbp_msg_obs_dep_b_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 2568200; - test_msg.header.t.wn = 1787; - test_msg.n_obs = 6; - - test_msg.obs[0].L.f = 165; - test_msg.obs[0].L.i = 117912057; - test_msg.obs[0].P = 2243649790; - test_msg.obs[0].cn0 = 156; - test_msg.obs[0].lock = 0; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 202; - - test_msg.obs[1].L.f = 106; - test_msg.obs[1].L.i = 129900811; - test_msg.obs[1].P = 2471880049; - test_msg.obs[1].cn0 = 143; - test_msg.obs[1].lock = 0; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 203; - - test_msg.obs[2].L.f = 159; - test_msg.obs[2].L.i = 122530275; - test_msg.obs[2].P = 2331530678; - test_msg.obs[2].cn0 = 150; - test_msg.obs[2].lock = 0; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 208; - - test_msg.obs[3].L.f = 7; - test_msg.obs[3].L.i = 119281418; - test_msg.obs[3].P = 2269714449; - test_msg.obs[3].cn0 = 156; - test_msg.obs[3].lock = 0; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 212; - - test_msg.obs[4].L.f = 186; - test_msg.obs[4].L.i = 109692070; - test_msg.obs[4].P = 2087295852; - test_msg.obs[4].cn0 = 170; - test_msg.obs[4].lock = 0; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 217; - - test_msg.obs[5].L.f = 236; - test_msg.obs[5].L.i = 123339597; - test_msg.obs[5].P = 2347011798; - test_msg.obs[5].cn0 = 151; - test_msg.obs[5].lock = 0; - test_msg.obs[5].sid.code = 0; - test_msg.obs[5].sid.reserved = 0; - test_msg.obs[5].sid.sat = 218; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 2568200) - << "incorrect value for last_msg_.header.t.tow, expected 2568200, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1787) - << "incorrect value for last_msg_.header.t.wn, expected 1787, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 6) - << "incorrect value for last_msg_.n_obs, expected 6, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 165) - << "incorrect value for last_msg_.obs[0].L.f, expected 165, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 117912057) - << "incorrect value for last_msg_.obs[0].L.i, expected 117912057, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2243649790) - << "incorrect value for last_msg_.obs[0].P, expected 2243649790, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 156) - << "incorrect value for last_msg_.obs[0].cn0, expected 156, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 0) - << "incorrect value for last_msg_.obs[0].lock, expected 0, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 202) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 202, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 106) - << "incorrect value for last_msg_.obs[1].L.f, expected 106, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 129900811) - << "incorrect value for last_msg_.obs[1].L.i, expected 129900811, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2471880049) - << "incorrect value for last_msg_.obs[1].P, expected 2471880049, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 143) - << "incorrect value for last_msg_.obs[1].cn0, expected 143, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 0) - << "incorrect value for last_msg_.obs[1].lock, expected 0, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 203) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 203, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 159) - << "incorrect value for last_msg_.obs[2].L.f, expected 159, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 122530275) - << "incorrect value for last_msg_.obs[2].L.i, expected 122530275, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2331530678) - << "incorrect value for last_msg_.obs[2].P, expected 2331530678, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 150) - << "incorrect value for last_msg_.obs[2].cn0, expected 150, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 0) - << "incorrect value for last_msg_.obs[2].lock, expected 0, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 208) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 208, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 7) - << "incorrect value for last_msg_.obs[3].L.f, expected 7, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 119281418) - << "incorrect value for last_msg_.obs[3].L.i, expected 119281418, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2269714449) - << "incorrect value for last_msg_.obs[3].P, expected 2269714449, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 156) - << "incorrect value for last_msg_.obs[3].cn0, expected 156, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 0) - << "incorrect value for last_msg_.obs[3].lock, expected 0, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 212) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 212, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 186) - << "incorrect value for last_msg_.obs[4].L.f, expected 186, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 109692070) - << "incorrect value for last_msg_.obs[4].L.i, expected 109692070, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 2087295852) - << "incorrect value for last_msg_.obs[4].P, expected 2087295852, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 170) - << "incorrect value for last_msg_.obs[4].cn0, expected 170, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 0) - << "incorrect value for last_msg_.obs[4].lock, expected 0, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 217) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 217, is " - << last_msg_.obs[4].sid.sat; - EXPECT_EQ(last_msg_.obs[5].L.f, 236) - << "incorrect value for last_msg_.obs[5].L.f, expected 236, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 123339597) - << "incorrect value for last_msg_.obs[5].L.i, expected 123339597, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 2347011798) - << "incorrect value for last_msg_.obs[5].P, expected 2347011798, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 151) - << "incorrect value for last_msg_.obs[5].cn0, expected 151, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].lock, 0) - << "incorrect value for last_msg_.obs[5].lock, expected 0, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].sid.code, 0) - << "incorrect value for last_msg_.obs[5].sid.code, expected 0, is " - << last_msg_.obs[5].sid.code; - EXPECT_EQ(last_msg_.obs[5].sid.reserved, 0) - << "incorrect value for last_msg_.obs[5].sid.reserved, expected 0, is " - << last_msg_.obs[5].sid.reserved; - EXPECT_EQ(last_msg_.obs[5].sid.sat, 218) - << "incorrect value for last_msg_.obs[5].sid.sat, expected 218, is " - << last_msg_.obs[5].sid.sat; +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + return sbp_msg_obs_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_b_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_b_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.code, greater.obs[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.reserved, + greater.obs[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_b_t lesser = info.test_msg; + sbp_msg_obs_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.sat, greater.obs[5].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepB); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_b, info.test_msg); } + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[103]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 103); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 103), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 103); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepB, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepB4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepB, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgObsDepC.cc b/c/test/cpp/auto_check_sbp_observation_MsgObsDepC.cc index 450c1271b5..973b441e27 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgObsDepC.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgObsDepC.cc @@ -16,66 +16,318 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgObsDepC0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgObsDepC0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObsDepC0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObsDepC0() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 414670600); + assign(test_msg_.header.t.wn, 1898); + assign(test_msg_.n_obs, 5); + + assign(test_msg_.obs[0].L.f, 231); + assign(test_msg_.obs[0].L.i, -565647); + assign(test_msg_.obs[0].P, 1347025534); + assign(test_msg_.obs[0].cn0, 163); + assign(test_msg_.obs[0].lock, 58853); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 4); + + assign(test_msg_.obs[1].L.f, 196); + assign(test_msg_.obs[1].L.i, -355503); + assign(test_msg_.obs[1].P, 1180752956); + assign(test_msg_.obs[1].cn0, 208); + assign(test_msg_.obs[1].lock, 7188); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 6); + + assign(test_msg_.obs[2].L.f, 110); + assign(test_msg_.obs[2].L.i, -902116); + assign(test_msg_.obs[2].P, 1295924728); + assign(test_msg_.obs[2].cn0, 171); + assign(test_msg_.obs[2].lock, 45748); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 7); + + assign(test_msg_.obs[3].L.f, 41); + assign(test_msg_.obs[3].L.i, 861612); + assign(test_msg_.obs[3].P, 1304319213); + assign(test_msg_.obs[3].cn0, 170); + assign(test_msg_.obs[3].lock, 42217); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 10); + + assign(test_msg_.obs[4].L.f, 19); + assign(test_msg_.obs[4].L.i, 1424624); + assign(test_msg_.obs[4].P, 1258902820); + assign(test_msg_.obs[4].cn0, 182); + assign(test_msg_.obs[4].lock, 53700); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 12); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepC, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_c, sizeof(msg->obs_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_c, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepC); + info.sender_id = 38982; + info.preamble = 0x55; + info.crc = 0xafbe; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 87; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_dep_c_t &lesser, + const sbp_msg_obs_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgObsDepC0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_c_t test_msg_{}; + uint8_t encoded_frame_[87 + 8] = { 85, 73, 0, 70, 152, 87, 8, 95, 183, 24, 106, 7, 32, 126, 250, 73, 80, 113, 94, 247, 255, 231, 163, 229, 229, 4, 0, 0, 0, 60, 220, 96, 70, 81, 147, 250, 255, 196, 208, 20, 28, 6, 0, 0, 0, 248, 61, 62, @@ -83,1108 +335,3876 @@ TEST_F(Test_auto_check_sbp_observation_MsgObsDepC0, Test) { 77, 172, 37, 13, 0, 41, 170, 233, 164, 10, 0, 0, 0, 36, 85, 9, 75, 240, 188, 21, 0, 19, 182, 196, 209, 12, 0, 0, 0, 190, 175, }; + uint8_t encoded_payload_[87] = { + 8, 95, 183, 24, 106, 7, 32, 126, 250, 73, 80, 113, 94, 247, 255, + 231, 163, 229, 229, 4, 0, 0, 0, 60, 220, 96, 70, 81, 147, 250, + 255, 196, 208, 20, 28, 6, 0, 0, 0, 248, 61, 62, 77, 28, 60, + 242, 255, 110, 171, 180, 178, 7, 0, 0, 0, 237, 84, 190, 77, 172, + 37, 13, 0, 41, 170, 233, 164, 10, 0, 0, 0, 36, 85, 9, 75, + 240, 188, 21, 0, 19, 182, 196, 209, 12, 0, 0, 0, + }; +}; - sbp_msg_obs_dep_c_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 414670600; - test_msg.header.t.wn = 1898; - test_msg.n_obs = 5; - - test_msg.obs[0].L.f = 231; - test_msg.obs[0].L.i = -565647; - test_msg.obs[0].P = 1347025534; - test_msg.obs[0].cn0 = 163; - test_msg.obs[0].lock = 58853; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 4; - - test_msg.obs[1].L.f = 196; - test_msg.obs[1].L.i = -355503; - test_msg.obs[1].P = 1180752956; - test_msg.obs[1].cn0 = 208; - test_msg.obs[1].lock = 7188; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 6; - - test_msg.obs[2].L.f = 110; - test_msg.obs[2].L.i = -902116; - test_msg.obs[2].P = 1295924728; - test_msg.obs[2].cn0 = 171; - test_msg.obs[2].lock = 45748; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 7; - - test_msg.obs[3].L.f = 41; - test_msg.obs[3].L.i = 861612; - test_msg.obs[3].P = 1304319213; - test_msg.obs[3].cn0 = 170; - test_msg.obs[3].lock = 42217; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 10; - - test_msg.obs[4].L.f = 19; - test_msg.obs[4].L.i = 1424624; - test_msg.obs[4].P = 1258902820; - test_msg.obs[4].cn0 = 182; - test_msg.obs[4].lock = 53700; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 12; - - EXPECT_EQ(send_message(38982, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 38982); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 414670600) - << "incorrect value for last_msg_.header.t.tow, expected 414670600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1898) - << "incorrect value for last_msg_.header.t.wn, expected 1898, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 5) - << "incorrect value for last_msg_.n_obs, expected 5, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 231) - << "incorrect value for last_msg_.obs[0].L.f, expected 231, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -565647) - << "incorrect value for last_msg_.obs[0].L.i, expected -565647, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1347025534) - << "incorrect value for last_msg_.obs[0].P, expected 1347025534, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 163) - << "incorrect value for last_msg_.obs[0].cn0, expected 163, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 58853) - << "incorrect value for last_msg_.obs[0].lock, expected 58853, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 4) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 4, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 196) - << "incorrect value for last_msg_.obs[1].L.f, expected 196, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, -355503) - << "incorrect value for last_msg_.obs[1].L.i, expected -355503, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1180752956) - << "incorrect value for last_msg_.obs[1].P, expected 1180752956, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 208) - << "incorrect value for last_msg_.obs[1].cn0, expected 208, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 7188) - << "incorrect value for last_msg_.obs[1].lock, expected 7188, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 6) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 6, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 110) - << "incorrect value for last_msg_.obs[2].L.f, expected 110, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -902116) - << "incorrect value for last_msg_.obs[2].L.i, expected -902116, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1295924728) - << "incorrect value for last_msg_.obs[2].P, expected 1295924728, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 171) - << "incorrect value for last_msg_.obs[2].cn0, expected 171, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 45748) - << "incorrect value for last_msg_.obs[2].lock, expected 45748, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 7) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 7, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 41) - << "incorrect value for last_msg_.obs[3].L.f, expected 41, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 861612) - << "incorrect value for last_msg_.obs[3].L.i, expected 861612, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 1304319213) - << "incorrect value for last_msg_.obs[3].P, expected 1304319213, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 170) - << "incorrect value for last_msg_.obs[3].cn0, expected 170, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 42217) - << "incorrect value for last_msg_.obs[3].lock, expected 42217, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 10) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 10, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 19) - << "incorrect value for last_msg_.obs[4].L.f, expected 19, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 1424624) - << "incorrect value for last_msg_.obs[4].L.i, expected 1424624, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1258902820) - << "incorrect value for last_msg_.obs[4].P, expected 1258902820, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 182) - << "incorrect value for last_msg_.obs[4].cn0, expected 182, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 53700) - << "incorrect value for last_msg_.obs[4].lock, expected 53700, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 12) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 12, is " - << last_msg_.obs[4].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepC1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepC1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_c_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepC, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + EXPECT_EQ( + sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + for (uint8_t i = 0; i < 87; i++) { + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_observation_MsgObsDepC1, Test) { - uint8_t encoded_frame[] = { - 85, 73, 0, 70, 152, 55, 8, 95, 183, 24, 106, 7, 33, 68, 166, 75, - 77, 186, 230, 24, 0, 101, 186, 162, 102, 16, 0, 0, 0, 87, 255, 155, - 69, 74, 158, 5, 0, 26, 190, 206, 30, 27, 0, 0, 0, 64, 89, 124, - 68, 26, 22, 3, 0, 114, 217, 225, 73, 29, 0, 0, 0, 37, 179, - }; + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_obs_dep_c_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 414670600; - test_msg.header.t.wn = 1898; - test_msg.n_obs = 3; - - test_msg.obs[0].L.f = 101; - test_msg.obs[0].L.i = 1631930; - test_msg.obs[0].P = 1296803396; - test_msg.obs[0].cn0 = 186; - test_msg.obs[0].lock = 26274; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 16; - - test_msg.obs[1].L.f = 26; - test_msg.obs[1].L.i = 368202; - test_msg.obs[1].P = 1167851351; - test_msg.obs[1].cn0 = 190; - test_msg.obs[1].lock = 7886; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 27; - - test_msg.obs[2].L.f = 114; - test_msg.obs[2].L.i = 202266; - test_msg.obs[2].P = 1149000000; - test_msg.obs[2].cn0 = 217; - test_msg.obs[2].lock = 18913; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 29; - - EXPECT_EQ(send_message(38982, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 38982); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 414670600) - << "incorrect value for last_msg_.header.t.tow, expected 414670600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1898) - << "incorrect value for last_msg_.header.t.wn, expected 1898, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 3) - << "incorrect value for last_msg_.n_obs, expected 3, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 101) - << "incorrect value for last_msg_.obs[0].L.f, expected 101, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 1631930) - << "incorrect value for last_msg_.obs[0].L.i, expected 1631930, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1296803396) - << "incorrect value for last_msg_.obs[0].P, expected 1296803396, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 186) - << "incorrect value for last_msg_.obs[0].cn0, expected 186, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 26274) - << "incorrect value for last_msg_.obs[0].lock, expected 26274, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 16) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 16, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 26) - << "incorrect value for last_msg_.obs[1].L.f, expected 26, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 368202) - << "incorrect value for last_msg_.obs[1].L.i, expected 368202, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1167851351) - << "incorrect value for last_msg_.obs[1].P, expected 1167851351, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 190) - << "incorrect value for last_msg_.obs[1].cn0, expected 190, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 7886) - << "incorrect value for last_msg_.obs[1].lock, expected 7886, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 27) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 27, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 114) - << "incorrect value for last_msg_.obs[2].L.f, expected 114, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 202266) - << "incorrect value for last_msg_.obs[2].L.i, expected 202266, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1149000000) - << "incorrect value for last_msg_.obs[2].P, expected 1149000000, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 217) - << "incorrect value for last_msg_.obs[2].cn0, expected 217, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 18913) - << "incorrect value for last_msg_.obs[2].lock, expected 18913, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 29) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 29, is " - << last_msg_.obs[2].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepC2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepC2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + return sbp_msg_obs_dep_c_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_c_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_observation_MsgObsDepC2, Test) { - uint8_t encoded_frame[] = { - 85, 73, 0, 0, 0, 87, 8, 95, 183, 24, 106, 7, 32, 217, 251, 73, - 80, 9, 72, 248, 255, 30, 168, 113, 81, 4, 0, 0, 0, 211, 220, 96, - 70, 198, 107, 251, 255, 115, 195, 53, 144, 6, 0, 0, 0, 77, 61, 62, - 77, 40, 161, 243, 255, 130, 176, 93, 142, 7, 0, 0, 0, 1, 86, 190, - 77, 88, 77, 12, 0, 116, 199, 229, 213, 10, 0, 0, 0, 93, 85, 9, - 75, 64, 139, 20, 0, 120, 177, 196, 194, 12, 0, 0, 0, 141, 161, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_c_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepC); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_C"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - sbp_msg_obs_dep_c_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 414670600; - test_msg.header.t.wn = 1898; - test_msg.n_obs = 5; - - test_msg.obs[0].L.f = 30; - test_msg.obs[0].L.i = -505847; - test_msg.obs[0].P = 1347025881; - test_msg.obs[0].cn0 = 168; - test_msg.obs[0].lock = 20849; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 4; - - test_msg.obs[1].L.f = 115; - test_msg.obs[1].L.i = -300090; - test_msg.obs[1].P = 1180753107; - test_msg.obs[1].cn0 = 195; - test_msg.obs[1].lock = 36917; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 6; - - test_msg.obs[2].L.f = 130; - test_msg.obs[2].L.i = -810712; - test_msg.obs[2].P = 1295924557; - test_msg.obs[2].cn0 = 176; - test_msg.obs[2].lock = 36445; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 7; - - test_msg.obs[3].L.f = 116; - test_msg.obs[3].L.i = 806232; - test_msg.obs[3].P = 1304319489; - test_msg.obs[3].cn0 = 199; - test_msg.obs[3].lock = 54757; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 10; - - test_msg.obs[4].L.f = 120; - test_msg.obs[4].L.i = 1346368; - test_msg.obs[4].P = 1258902877; - test_msg.obs[4].cn0 = 177; - test_msg.obs[4].lock = 49860; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 12; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 414670600) - << "incorrect value for last_msg_.header.t.tow, expected 414670600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1898) - << "incorrect value for last_msg_.header.t.wn, expected 1898, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 5) - << "incorrect value for last_msg_.n_obs, expected 5, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 30) - << "incorrect value for last_msg_.obs[0].L.f, expected 30, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -505847) - << "incorrect value for last_msg_.obs[0].L.i, expected -505847, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1347025881) - << "incorrect value for last_msg_.obs[0].P, expected 1347025881, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 168) - << "incorrect value for last_msg_.obs[0].cn0, expected 168, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 20849) - << "incorrect value for last_msg_.obs[0].lock, expected 20849, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 4) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 4, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 115) - << "incorrect value for last_msg_.obs[1].L.f, expected 115, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, -300090) - << "incorrect value for last_msg_.obs[1].L.i, expected -300090, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1180753107) - << "incorrect value for last_msg_.obs[1].P, expected 1180753107, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 195) - << "incorrect value for last_msg_.obs[1].cn0, expected 195, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 36917) - << "incorrect value for last_msg_.obs[1].lock, expected 36917, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 6) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 6, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 130) - << "incorrect value for last_msg_.obs[2].L.f, expected 130, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -810712) - << "incorrect value for last_msg_.obs[2].L.i, expected -810712, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1295924557) - << "incorrect value for last_msg_.obs[2].P, expected 1295924557, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 176) - << "incorrect value for last_msg_.obs[2].cn0, expected 176, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 36445) - << "incorrect value for last_msg_.obs[2].lock, expected 36445, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 7) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 7, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 116) - << "incorrect value for last_msg_.obs[3].L.f, expected 116, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 806232) - << "incorrect value for last_msg_.obs[3].L.i, expected 806232, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 1304319489) - << "incorrect value for last_msg_.obs[3].P, expected 1304319489, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 199) - << "incorrect value for last_msg_.obs[3].cn0, expected 199, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 54757) - << "incorrect value for last_msg_.obs[3].lock, expected 54757, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 10) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 10, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 120) - << "incorrect value for last_msg_.obs[4].L.f, expected 120, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 1346368) - << "incorrect value for last_msg_.obs[4].L.i, expected 1346368, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1258902877) - << "incorrect value for last_msg_.obs[4].P, expected 1258902877, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 177) - << "incorrect value for last_msg_.obs[4].cn0, expected 177, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 49860) - << "incorrect value for last_msg_.obs[4].lock, expected 49860, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 12) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 12, is " - << last_msg_.obs[4].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepC3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepC, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepC, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepC1 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgObsDepC3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgObsDepC1() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 414670600); + assign(test_msg_.header.t.wn, 1898); + assign(test_msg_.n_obs, 3); + + assign(test_msg_.obs[0].L.f, 101); + assign(test_msg_.obs[0].L.i, 1631930); + assign(test_msg_.obs[0].P, 1296803396); + assign(test_msg_.obs[0].cn0, 186); + assign(test_msg_.obs[0].lock, 26274); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 16); + + assign(test_msg_.obs[1].L.f, 26); + assign(test_msg_.obs[1].L.i, 368202); + assign(test_msg_.obs[1].P, 1167851351); + assign(test_msg_.obs[1].cn0, 190); + assign(test_msg_.obs[1].lock, 7886); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 27); + + assign(test_msg_.obs[2].L.f, 114); + assign(test_msg_.obs[2].L.i, 202266); + assign(test_msg_.obs[2].P, 1149000000); + assign(test_msg_.obs[2].cn0, 217); + assign(test_msg_.obs[2].lock, 18913); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 29); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_observation_MsgObsDepC3, Test) { - uint8_t encoded_frame[] = { - 85, 73, 0, 0, 0, 55, 8, 95, 183, 24, 106, 7, 33, 70, 167, 75, - 77, 140, 136, 23, 0, 90, 187, 158, 129, 16, 0, 0, 0, 232, 255, 155, - 69, 45, 175, 5, 0, 17, 208, 175, 56, 27, 0, 0, 0, 64, 89, 124, - 68, 45, 96, 3, 0, 75, 185, 73, 206, 29, 0, 0, 0, 220, 158, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_obs_dep_c_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 414670600; - test_msg.header.t.wn = 1898; - test_msg.n_obs = 3; - - test_msg.obs[0].L.f = 90; - test_msg.obs[0].L.i = 1542284; - test_msg.obs[0].P = 1296803654; - test_msg.obs[0].cn0 = 187; - test_msg.obs[0].lock = 33182; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 16; - - test_msg.obs[1].L.f = 17; - test_msg.obs[1].L.i = 372525; - test_msg.obs[1].P = 1167851496; - test_msg.obs[1].cn0 = 208; - test_msg.obs[1].lock = 14511; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 27; - - test_msg.obs[2].L.f = 75; - test_msg.obs[2].L.i = 221229; - test_msg.obs[2].P = 1149000000; - test_msg.obs[2].cn0 = 185; - test_msg.obs[2].lock = 52809; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 29; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 414670600) - << "incorrect value for last_msg_.header.t.tow, expected 414670600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1898) - << "incorrect value for last_msg_.header.t.wn, expected 1898, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 3) - << "incorrect value for last_msg_.n_obs, expected 3, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 90) - << "incorrect value for last_msg_.obs[0].L.f, expected 90, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 1542284) - << "incorrect value for last_msg_.obs[0].L.i, expected 1542284, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1296803654) - << "incorrect value for last_msg_.obs[0].P, expected 1296803654, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 187) - << "incorrect value for last_msg_.obs[0].cn0, expected 187, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 33182) - << "incorrect value for last_msg_.obs[0].lock, expected 33182, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 16) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 16, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 17) - << "incorrect value for last_msg_.obs[1].L.f, expected 17, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 372525) - << "incorrect value for last_msg_.obs[1].L.i, expected 372525, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1167851496) - << "incorrect value for last_msg_.obs[1].P, expected 1167851496, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 208) - << "incorrect value for last_msg_.obs[1].cn0, expected 208, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 14511) - << "incorrect value for last_msg_.obs[1].lock, expected 14511, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 27) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 27, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 75) - << "incorrect value for last_msg_.obs[2].L.f, expected 75, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 221229) - << "incorrect value for last_msg_.obs[2].L.i, expected 221229, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1149000000) - << "incorrect value for last_msg_.obs[2].P, expected 1149000000, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 185) - << "incorrect value for last_msg_.obs[2].cn0, expected 185, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 52809) - << "incorrect value for last_msg_.obs[2].lock, expected 52809, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 29) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 29, is " - << last_msg_.obs[2].sid.sat; -} -class Test_auto_check_sbp_observation_MsgObsDepC4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_MsgObsDepC4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepC, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_c, sizeof(msg->obs_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_c, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepC); + info.sender_id = 38982; + info.preamble = 0x55; + info.crc = 0xb325; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_c_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_c_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_dep_c_t &lesser, + const sbp_msg_obs_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_observation_MsgObsDepC4, Test) { - uint8_t encoded_frame[] = { - 85, 73, 0, 70, 152, 87, 208, 95, 183, 24, 106, 7, 32, 44, 8, 74, - 80, 86, 93, 247, 255, 57, 158, 229, 229, 4, 0, 0, 0, 224, 229, 96, - 70, 156, 146, 250, 255, 221, 200, 20, 28, 6, 0, 0, 0, 60, 82, 62, - 77, 93, 58, 242, 255, 39, 164, 180, 178, 7, 0, 0, 0, 222, 73, 190, - 77, 46, 39, 13, 0, 202, 181, 233, 164, 10, 0, 0, 0, 149, 64, 9, - 75, 114, 191, 21, 0, 249, 182, 196, 209, 12, 0, 0, 0, 112, 8, - }; + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_c_cmp(&greater, &lesser), 0); - sbp_msg_obs_dep_c_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 414670800; - test_msg.header.t.wn = 1898; - test_msg.n_obs = 5; - - test_msg.obs[0].L.f = 57; - test_msg.obs[0].L.i = -565930; - test_msg.obs[0].P = 1347029036; - test_msg.obs[0].cn0 = 158; - test_msg.obs[0].lock = 58853; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.reserved = 0; - test_msg.obs[0].sid.sat = 4; - - test_msg.obs[1].L.f = 221; - test_msg.obs[1].L.i = -355684; - test_msg.obs[1].P = 1180755424; - test_msg.obs[1].cn0 = 200; - test_msg.obs[1].lock = 7188; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.reserved = 0; - test_msg.obs[1].sid.sat = 6; - - test_msg.obs[2].L.f = 39; - test_msg.obs[2].L.i = -902563; - test_msg.obs[2].P = 1295929916; - test_msg.obs[2].cn0 = 164; - test_msg.obs[2].lock = 45748; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.reserved = 0; - test_msg.obs[2].sid.sat = 7; - - test_msg.obs[3].L.f = 202; - test_msg.obs[3].L.i = 861998; - test_msg.obs[3].P = 1304316382; - test_msg.obs[3].cn0 = 181; - test_msg.obs[3].lock = 42217; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.reserved = 0; - test_msg.obs[3].sid.sat = 10; - - test_msg.obs[4].L.f = 249; - test_msg.obs[4].L.i = 1425266; - test_msg.obs[4].P = 1258897557; - test_msg.obs[4].cn0 = 182; - test_msg.obs[4].lock = 53700; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.reserved = 0; - test_msg.obs[4].sid.sat = 12; - - EXPECT_EQ(send_message(38982, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 38982); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 414670800) - << "incorrect value for last_msg_.header.t.tow, expected 414670800, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1898) - << "incorrect value for last_msg_.header.t.wn, expected 1898, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 5) - << "incorrect value for last_msg_.n_obs, expected 5, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 57) - << "incorrect value for last_msg_.obs[0].L.f, expected 57, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -565930) - << "incorrect value for last_msg_.obs[0].L.i, expected -565930, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1347029036) - << "incorrect value for last_msg_.obs[0].P, expected 1347029036, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 158) - << "incorrect value for last_msg_.obs[0].cn0, expected 158, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 58853) - << "incorrect value for last_msg_.obs[0].lock, expected 58853, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.reserved, 0) - << "incorrect value for last_msg_.obs[0].sid.reserved, expected 0, is " - << last_msg_.obs[0].sid.reserved; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 4) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 4, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[1].L.f, 221) - << "incorrect value for last_msg_.obs[1].L.f, expected 221, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, -355684) - << "incorrect value for last_msg_.obs[1].L.i, expected -355684, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1180755424) - << "incorrect value for last_msg_.obs[1].P, expected 1180755424, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 200) - << "incorrect value for last_msg_.obs[1].cn0, expected 200, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 7188) - << "incorrect value for last_msg_.obs[1].lock, expected 7188, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.reserved, 0) - << "incorrect value for last_msg_.obs[1].sid.reserved, expected 0, is " - << last_msg_.obs[1].sid.reserved; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 6) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 6, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[2].L.f, 39) - << "incorrect value for last_msg_.obs[2].L.f, expected 39, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -902563) - << "incorrect value for last_msg_.obs[2].L.i, expected -902563, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1295929916) - << "incorrect value for last_msg_.obs[2].P, expected 1295929916, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 164) - << "incorrect value for last_msg_.obs[2].cn0, expected 164, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 45748) - << "incorrect value for last_msg_.obs[2].lock, expected 45748, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.reserved, 0) - << "incorrect value for last_msg_.obs[2].sid.reserved, expected 0, is " - << last_msg_.obs[2].sid.reserved; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 7) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 7, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[3].L.f, 202) - << "incorrect value for last_msg_.obs[3].L.f, expected 202, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 861998) - << "incorrect value for last_msg_.obs[3].L.i, expected 861998, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 1304316382) - << "incorrect value for last_msg_.obs[3].P, expected 1304316382, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 181) - << "incorrect value for last_msg_.obs[3].cn0, expected 181, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 42217) - << "incorrect value for last_msg_.obs[3].lock, expected 42217, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.reserved, 0) - << "incorrect value for last_msg_.obs[3].sid.reserved, expected 0, is " - << last_msg_.obs[3].sid.reserved; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 10) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 10, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[4].L.f, 249) - << "incorrect value for last_msg_.obs[4].L.f, expected 249, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 1425266) - << "incorrect value for last_msg_.obs[4].L.i, expected 1425266, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1258897557) - << "incorrect value for last_msg_.obs[4].P, expected 1258897557, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 182) - << "incorrect value for last_msg_.obs[4].cn0, expected 182, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 53700) - << "incorrect value for last_msg_.obs[4].lock, expected 53700, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.reserved, 0) - << "incorrect value for last_msg_.obs[4].sid.reserved, expected 0, is " - << last_msg_.obs[4].sid.reserved; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 12) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 12, is " - << last_msg_.obs[4].sid.sat; -} + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_c_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 73, 0, 70, 152, 55, 8, 95, 183, 24, 106, 7, 33, 68, 166, 75, + 77, 186, 230, 24, 0, 101, 186, 162, 102, 16, 0, 0, 0, 87, 255, 155, + 69, 74, 158, 5, 0, 26, 190, 206, 30, 27, 0, 0, 0, 64, 89, 124, + 68, 26, 22, 3, 0, 114, 217, 225, 73, 29, 0, 0, 0, 37, 179, + }; + uint8_t encoded_payload_[55] = { + 8, 95, 183, 24, 106, 7, 33, 68, 166, 75, 77, 186, 230, 24, + 0, 101, 186, 162, 102, 16, 0, 0, 0, 87, 255, 155, 69, 74, + 158, 5, 0, 26, 190, 206, 30, 27, 0, 0, 0, 64, 89, 124, + 68, 26, 22, 3, 0, 114, 217, 225, 73, 29, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_c_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepC, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ( + sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + return sbp_msg_obs_dep_c_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_c_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_c_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepC); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_C"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepC, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepC, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepC2 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepC2() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 414670600); + assign(test_msg_.header.t.wn, 1898); + assign(test_msg_.n_obs, 5); + + assign(test_msg_.obs[0].L.f, 30); + assign(test_msg_.obs[0].L.i, -505847); + assign(test_msg_.obs[0].P, 1347025881); + assign(test_msg_.obs[0].cn0, 168); + assign(test_msg_.obs[0].lock, 20849); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 4); + + assign(test_msg_.obs[1].L.f, 115); + assign(test_msg_.obs[1].L.i, -300090); + assign(test_msg_.obs[1].P, 1180753107); + assign(test_msg_.obs[1].cn0, 195); + assign(test_msg_.obs[1].lock, 36917); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 6); + + assign(test_msg_.obs[2].L.f, 130); + assign(test_msg_.obs[2].L.i, -810712); + assign(test_msg_.obs[2].P, 1295924557); + assign(test_msg_.obs[2].cn0, 176); + assign(test_msg_.obs[2].lock, 36445); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 7); + + assign(test_msg_.obs[3].L.f, 116); + assign(test_msg_.obs[3].L.i, 806232); + assign(test_msg_.obs[3].P, 1304319489); + assign(test_msg_.obs[3].cn0, 199); + assign(test_msg_.obs[3].lock, 54757); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 10); + + assign(test_msg_.obs[4].L.f, 120); + assign(test_msg_.obs[4].L.i, 1346368); + assign(test_msg_.obs[4].P, 1258902877); + assign(test_msg_.obs[4].cn0, 177); + assign(test_msg_.obs[4].lock, 49860); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 12); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepC, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_c, sizeof(msg->obs_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_c, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepC); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0xa18d; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 87; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_c_t &lesser, + const sbp_msg_obs_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_c_t test_msg_{}; + uint8_t encoded_frame_[87 + 8] = { + 85, 73, 0, 0, 0, 87, 8, 95, 183, 24, 106, 7, 32, 217, 251, 73, + 80, 9, 72, 248, 255, 30, 168, 113, 81, 4, 0, 0, 0, 211, 220, 96, + 70, 198, 107, 251, 255, 115, 195, 53, 144, 6, 0, 0, 0, 77, 61, 62, + 77, 40, 161, 243, 255, 130, 176, 93, 142, 7, 0, 0, 0, 1, 86, 190, + 77, 88, 77, 12, 0, 116, 199, 229, 213, 10, 0, 0, 0, 93, 85, 9, + 75, 64, 139, 20, 0, 120, 177, 196, 194, 12, 0, 0, 0, 141, 161, + }; + uint8_t encoded_payload_[87] = { + 8, 95, 183, 24, 106, 7, 32, 217, 251, 73, 80, 9, 72, 248, 255, + 30, 168, 113, 81, 4, 0, 0, 0, 211, 220, 96, 70, 198, 107, 251, + 255, 115, 195, 53, 144, 6, 0, 0, 0, 77, 61, 62, 77, 40, 161, + 243, 255, 130, 176, 93, 142, 7, 0, 0, 0, 1, 86, 190, 77, 88, + 77, 12, 0, 116, 199, 229, 213, 10, 0, 0, 0, 93, 85, 9, 75, + 64, 139, 20, 0, 120, 177, 196, 194, 12, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_c_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepC, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + EXPECT_EQ( + sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + for (uint8_t i = 0; i < 87; i++) { + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + return sbp_msg_obs_dep_c_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_c_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_c_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepC); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_C"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepC, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepC, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepC3 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepC3() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 414670600); + assign(test_msg_.header.t.wn, 1898); + assign(test_msg_.n_obs, 3); + + assign(test_msg_.obs[0].L.f, 90); + assign(test_msg_.obs[0].L.i, 1542284); + assign(test_msg_.obs[0].P, 1296803654); + assign(test_msg_.obs[0].cn0, 187); + assign(test_msg_.obs[0].lock, 33182); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 16); + + assign(test_msg_.obs[1].L.f, 17); + assign(test_msg_.obs[1].L.i, 372525); + assign(test_msg_.obs[1].P, 1167851496); + assign(test_msg_.obs[1].cn0, 208); + assign(test_msg_.obs[1].lock, 14511); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 27); + + assign(test_msg_.obs[2].L.f, 75); + assign(test_msg_.obs[2].L.i, 221229); + assign(test_msg_.obs[2].P, 1149000000); + assign(test_msg_.obs[2].cn0, 185); + assign(test_msg_.obs[2].lock, 52809); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 29); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepC, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_c, sizeof(msg->obs_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_c, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepC); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0x9edc; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_c_t &lesser, + const sbp_msg_obs_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_c_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 73, 0, 0, 0, 55, 8, 95, 183, 24, 106, 7, 33, 70, 167, 75, + 77, 140, 136, 23, 0, 90, 187, 158, 129, 16, 0, 0, 0, 232, 255, 155, + 69, 45, 175, 5, 0, 17, 208, 175, 56, 27, 0, 0, 0, 64, 89, 124, + 68, 45, 96, 3, 0, 75, 185, 73, 206, 29, 0, 0, 0, 220, 158, + }; + uint8_t encoded_payload_[55] = { + 8, 95, 183, 24, 106, 7, 33, 70, 167, 75, 77, 140, 136, 23, + 0, 90, 187, 158, 129, 16, 0, 0, 0, 232, 255, 155, 69, 45, + 175, 5, 0, 17, 208, 175, 56, 27, 0, 0, 0, 64, 89, 124, + 68, 45, 96, 3, 0, 75, 185, 73, 206, 29, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_c_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepC, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ( + sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + return sbp_msg_obs_dep_c_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_c_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_c_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepC); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_C"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepC, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepC, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_MsgObsDepC4 : public ::testing::Test { + public: + Testauto_check_sbp_observation_MsgObsDepC4() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 414670800); + assign(test_msg_.header.t.wn, 1898); + assign(test_msg_.n_obs, 5); + + assign(test_msg_.obs[0].L.f, 57); + assign(test_msg_.obs[0].L.i, -565930); + assign(test_msg_.obs[0].P, 1347029036); + assign(test_msg_.obs[0].cn0, 158); + assign(test_msg_.obs[0].lock, 58853); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.reserved, 0); + assign(test_msg_.obs[0].sid.sat, 4); + + assign(test_msg_.obs[1].L.f, 221); + assign(test_msg_.obs[1].L.i, -355684); + assign(test_msg_.obs[1].P, 1180755424); + assign(test_msg_.obs[1].cn0, 200); + assign(test_msg_.obs[1].lock, 7188); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.reserved, 0); + assign(test_msg_.obs[1].sid.sat, 6); + + assign(test_msg_.obs[2].L.f, 39); + assign(test_msg_.obs[2].L.i, -902563); + assign(test_msg_.obs[2].P, 1295929916); + assign(test_msg_.obs[2].cn0, 164); + assign(test_msg_.obs[2].lock, 45748); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.reserved, 0); + assign(test_msg_.obs[2].sid.sat, 7); + + assign(test_msg_.obs[3].L.f, 202); + assign(test_msg_.obs[3].L.i, 861998); + assign(test_msg_.obs[3].P, 1304316382); + assign(test_msg_.obs[3].cn0, 181); + assign(test_msg_.obs[3].lock, 42217); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.reserved, 0); + assign(test_msg_.obs[3].sid.sat, 10); + + assign(test_msg_.obs[4].L.f, 249); + assign(test_msg_.obs[4].L.i, 1425266); + assign(test_msg_.obs[4].P, 1258897557); + assign(test_msg_.obs[4].cn0, 182); + assign(test_msg_.obs[4].lock, 53700); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.reserved, 0); + assign(test_msg_.obs[4].sid.sat, 12); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_c_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepC, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_c_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepC); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_c, sizeof(msg->obs_dep_c)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_c_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_c, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepC); + info.sender_id = 38982; + info.preamble = 0x55; + info.crc = 0x870; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 87; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_c_t &lesser, + const sbp_msg_obs_dep_c_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_c_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_c_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_c_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepC, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepC, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_c_t test_msg_{}; + uint8_t encoded_frame_[87 + 8] = { + 85, 73, 0, 70, 152, 87, 208, 95, 183, 24, 106, 7, 32, 44, 8, 74, + 80, 86, 93, 247, 255, 57, 158, 229, 229, 4, 0, 0, 0, 224, 229, 96, + 70, 156, 146, 250, 255, 221, 200, 20, 28, 6, 0, 0, 0, 60, 82, 62, + 77, 93, 58, 242, 255, 39, 164, 180, 178, 7, 0, 0, 0, 222, 73, 190, + 77, 46, 39, 13, 0, 202, 181, 233, 164, 10, 0, 0, 0, 149, 64, 9, + 75, 114, 191, 21, 0, 249, 182, 196, 209, 12, 0, 0, 0, 112, 8, + }; + uint8_t encoded_payload_[87] = { + 208, 95, 183, 24, 106, 7, 32, 44, 8, 74, 80, 86, 93, 247, 255, + 57, 158, 229, 229, 4, 0, 0, 0, 224, 229, 96, 70, 156, 146, 250, + 255, 221, 200, 20, 28, 6, 0, 0, 0, 60, 82, 62, 77, 93, 58, + 242, 255, 39, 164, 180, 178, 7, 0, 0, 0, 222, 73, 190, 77, 46, + 39, 13, 0, 202, 181, 233, 164, 10, 0, 0, 0, 149, 64, 9, 75, + 114, 191, 21, 0, 249, 182, 196, 209, 12, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_c_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepC, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepC, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + EXPECT_EQ( + sbp_msg_obs_dep_c_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + + for (uint8_t i = 0; i < 87; i++) { + EXPECT_EQ(sbp_msg_obs_dep_c_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepC, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + return sbp_msg_obs_dep_c_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_c_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_c_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_c_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_c_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepC, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.reserved, + greater.obs[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.reserved, + greater.obs[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.reserved, + greater.obs[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.reserved, + greater.obs[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.reserved, + greater.obs[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_c_t lesser = info.test_msg; + sbp_msg_obs_dep_c_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepC); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_C"); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_c_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_c_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_c, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_c, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[87]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 87); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 87), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_c_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 87); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepC, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgObsDepC4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepC, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgOsr.cc b/c/test/cpp/auto_check_sbp_observation_MsgOsr.cc index 40c5b4dd87..72abf97d4c 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgOsr.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgOsr.cc @@ -16,65 +16,402 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgOsr0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgOsr0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgOsr0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgOsr0() { + assign(test_msg_.header.n_obs, 64); + assign(test_msg_.header.t.ns_residual, 0); + assign(test_msg_.header.t.tow, 501867000); + assign(test_msg_.header.t.wn, 2152); + assign(test_msg_.n_obs, 12); + + assign(test_msg_.obs[0].L.f, 66); + assign(test_msg_.obs[0].L.i, 121567974); + assign(test_msg_.obs[0].P, 1156681547); + assign(test_msg_.obs[0].flags, 3); + assign(test_msg_.obs[0].iono_std, 13); + assign(test_msg_.obs[0].lock, 15); + assign(test_msg_.obs[0].range_std, 7); + assign(test_msg_.obs[0].sid.code, 0); + assign(test_msg_.obs[0].sid.sat, 1); + assign(test_msg_.obs[0].tropo_std, 7); + + assign(test_msg_.obs[1].L.f, 75); + assign(test_msg_.obs[1].L.i, 111817196); + assign(test_msg_.obs[1].P, 1063905486); + assign(test_msg_.obs[1].flags, 3); + assign(test_msg_.obs[1].iono_std, 13); + assign(test_msg_.obs[1].lock, 15); + assign(test_msg_.obs[1].range_std, 3); + assign(test_msg_.obs[1].sid.code, 0); + assign(test_msg_.obs[1].sid.sat, 13); + assign(test_msg_.obs[1].tropo_std, 3); + + assign(test_msg_.obs[2].L.f, 128); + assign(test_msg_.obs[2].L.i, 110692129); + assign(test_msg_.obs[2].P, 1053200685); + assign(test_msg_.obs[2].flags, 3); + assign(test_msg_.obs[2].iono_std, 13); + assign(test_msg_.obs[2].lock, 15); + assign(test_msg_.obs[2].range_std, 3); + assign(test_msg_.obs[2].sid.code, 0); + assign(test_msg_.obs[2].sid.sat, 14); + assign(test_msg_.obs[2].tropo_std, 3); + + assign(test_msg_.obs[3].L.f, 127); + assign(test_msg_.obs[3].L.i, 119549583); + assign(test_msg_.obs[3].P, 1137476697); + assign(test_msg_.obs[3].flags, 3); + assign(test_msg_.obs[3].iono_std, 13); + assign(test_msg_.obs[3].lock, 15); + assign(test_msg_.obs[3].range_std, 5); + assign(test_msg_.obs[3].sid.code, 0); + assign(test_msg_.obs[3].sid.sat, 15); + assign(test_msg_.obs[3].tropo_std, 5); + + assign(test_msg_.obs[4].L.f, 55); + assign(test_msg_.obs[4].L.i, 106934294); + assign(test_msg_.obs[4].P, 1017446132); + assign(test_msg_.obs[4].flags, 3); + assign(test_msg_.obs[4].iono_std, 0); + assign(test_msg_.obs[4].lock, 15); + assign(test_msg_.obs[4].range_std, 2); + assign(test_msg_.obs[4].sid.code, 0); + assign(test_msg_.obs[4].sid.sat, 17); + assign(test_msg_.obs[4].tropo_std, 2); + + assign(test_msg_.obs[5].L.f, 108); + assign(test_msg_.obs[5].L.i, 110024343); + assign(test_msg_.obs[5].P, 1046846826); + assign(test_msg_.obs[5].flags, 3); + assign(test_msg_.obs[5].iono_std, 13); + assign(test_msg_.obs[5].lock, 15); + assign(test_msg_.obs[5].range_std, 3); + assign(test_msg_.obs[5].sid.code, 0); + assign(test_msg_.obs[5].sid.sat, 19); + assign(test_msg_.obs[5].tropo_std, 3); + + assign(test_msg_.obs[6].L.f, 206); + assign(test_msg_.obs[6].L.i, 111507381); + assign(test_msg_.obs[6].P, 1060957521); + assign(test_msg_.obs[6].flags, 3); + assign(test_msg_.obs[6].iono_std, 13); + assign(test_msg_.obs[6].lock, 15); + assign(test_msg_.obs[6].range_std, 3); + assign(test_msg_.obs[6].sid.code, 0); + assign(test_msg_.obs[6].sid.sat, 28); + assign(test_msg_.obs[6].tropo_std, 3); + + assign(test_msg_.obs[7].L.f, 200); + assign(test_msg_.obs[7].L.i, 113614775); + assign(test_msg_.obs[7].P, 1081009286); + assign(test_msg_.obs[7].flags, 3); + assign(test_msg_.obs[7].iono_std, 13); + assign(test_msg_.obs[7].lock, 15); + assign(test_msg_.obs[7].range_std, 3); + assign(test_msg_.obs[7].sid.code, 0); + assign(test_msg_.obs[7].sid.sat, 30); + assign(test_msg_.obs[7].tropo_std, 3); + + assign(test_msg_.obs[8].L.f, 170); + assign(test_msg_.obs[8].L.i, 94728270); + assign(test_msg_.obs[8].P, 1156681781); + assign(test_msg_.obs[8].flags, 3); + assign(test_msg_.obs[8].iono_std, 21); + assign(test_msg_.obs[8].lock, 15); + assign(test_msg_.obs[8].range_std, 7); + assign(test_msg_.obs[8].sid.code, 6); + assign(test_msg_.obs[8].sid.sat, 1); + assign(test_msg_.obs[8].tropo_std, 7); + + assign(test_msg_.obs[9].L.f, 129); + assign(test_msg_.obs[9].L.i, 87130275); + assign(test_msg_.obs[9].P, 1063905531); + assign(test_msg_.obs[9].flags, 3); + assign(test_msg_.obs[9].iono_std, 21); + assign(test_msg_.obs[9].lock, 15); + assign(test_msg_.obs[9].range_std, 3); + assign(test_msg_.obs[9].sid.code, 6); + assign(test_msg_.obs[9].sid.sat, 13); + assign(test_msg_.obs[9].tropo_std, 3); + + assign(test_msg_.obs[10].L.f, 46); + assign(test_msg_.obs[10].L.i, 86253605); + assign(test_msg_.obs[10].P, 1053200752); + assign(test_msg_.obs[10].flags, 3); + assign(test_msg_.obs[10].iono_std, 21); + assign(test_msg_.obs[10].lock, 15); + assign(test_msg_.obs[10].range_std, 3); + assign(test_msg_.obs[10].sid.code, 6); + assign(test_msg_.obs[10].sid.sat, 14); + assign(test_msg_.obs[10].tropo_std, 3); + + assign(test_msg_.obs[11].L.f, 95); + assign(test_msg_.obs[11].L.i, 93155512); + assign(test_msg_.obs[11].P, 1137476774); + assign(test_msg_.obs[11].flags, 3); + assign(test_msg_.obs[11].iono_std, 21); + assign(test_msg_.obs[11].lock, 15); + assign(test_msg_.obs[11].range_std, 5); + assign(test_msg_.obs[11].sid.code, 6); + assign(test_msg_.obs[11].sid.sat, 15); + assign(test_msg_.obs[11].tropo_std, 5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_osr_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, const sbp_msg_osr_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgOsr, &CHandler::callback_static, this, + &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_osr_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgOsr); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->osr, sizeof(msg->osr)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_osr_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.osr, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgOsr); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0xe379; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 239; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, const sbp_msg_osr_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_osr_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_osr_t &lesser, + const sbp_msg_osr_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_osr_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_osr_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_osr_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_osr_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgOsr, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgOsr, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgOsr, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT(sbp_message_cmp(SbpMsgOsr, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_observation_MsgOsr0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_osr_t test_msg_{}; + uint8_t encoded_frame_[239 + 8] = { 85, 64, 6, 0, 0, 239, 248, 225, 233, 29, 0, 0, 0, 0, 104, 8, 64, 75, 143, 241, 68, 230, 250, 62, 7, 66, 15, 3, 1, 0, 13, 0, 7, 0, 7, 0, 206, 232, 105, 63, 236, 49, 170, 6, 75, @@ -93,531 +430,1074 @@ TEST_F(Test_auto_check_sbp_observation_MsgOsr0, Test) { 0, 166, 132, 204, 67, 184, 112, 141, 5, 95, 15, 3, 15, 6, 21, 0, 5, 0, 5, 0, 121, 227, }; + uint8_t encoded_payload_[239] = { + 248, 225, 233, 29, 0, 0, 0, 0, 104, 8, 64, 75, 143, 241, 68, + 230, 250, 62, 7, 66, 15, 3, 1, 0, 13, 0, 7, 0, 7, 0, + 206, 232, 105, 63, 236, 49, 170, 6, 75, 15, 3, 13, 0, 13, 0, + 3, 0, 3, 0, 45, 145, 198, 62, 33, 7, 153, 6, 128, 15, 3, + 14, 0, 13, 0, 3, 0, 3, 0, 89, 132, 204, 67, 143, 46, 32, + 7, 127, 15, 3, 15, 0, 13, 0, 5, 0, 5, 0, 244, 254, 164, + 60, 22, 176, 95, 6, 55, 15, 3, 17, 0, 0, 0, 2, 0, 2, + 0, 106, 157, 101, 62, 151, 214, 142, 6, 108, 15, 3, 19, 0, 13, + 0, 3, 0, 3, 0, 81, 237, 60, 63, 181, 119, 165, 6, 206, 15, + 3, 28, 0, 13, 0, 3, 0, 3, 0, 134, 228, 110, 64, 183, 159, + 197, 6, 200, 15, 3, 30, 0, 13, 0, 3, 0, 3, 0, 53, 144, + 241, 68, 78, 112, 165, 5, 170, 15, 3, 1, 6, 21, 0, 7, 0, + 7, 0, 251, 232, 105, 63, 163, 128, 49, 5, 129, 15, 3, 13, 6, + 21, 0, 3, 0, 3, 0, 112, 145, 198, 62, 37, 32, 36, 5, 46, + 15, 3, 14, 6, 21, 0, 3, 0, 3, 0, 166, 132, 204, 67, 184, + 112, 141, 5, 95, 15, 3, 15, 6, 21, 0, 5, 0, 5, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_osr_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgOsr, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[239]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_osr_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 239); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 239), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgOsr, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 239); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 239), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[239]; + + EXPECT_EQ(sbp_msg_osr_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 239), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgOsr0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[239]; + + for (uint8_t i = 0; i < 239; i++) { + EXPECT_EQ(sbp_msg_osr_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_osr_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_osr_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 239); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgOsr, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 239); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_osr_t msg{}; + + EXPECT_EQ(sbp_msg_osr_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_MsgOsr0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_osr_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_osr_t t{}; + return sbp_msg_osr_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_osr_t t{}; + t.n_obs = 1; + return sbp_msg_osr_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_osr_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_osr_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgOsr, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.ns_residual, + greater.header.t.ns_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].flags, greater.obs[0].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].iono_std, greater.obs[0].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].range_std, greater.obs[0].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.code, greater.obs[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].sid.sat, greater.obs[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].tropo_std, greater.obs[0].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].flags, greater.obs[1].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].iono_std, greater.obs[1].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].range_std, greater.obs[1].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.code, greater.obs[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].sid.sat, greater.obs[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].tropo_std, greater.obs[1].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].flags, greater.obs[2].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].iono_std, greater.obs[2].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].range_std, greater.obs[2].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.code, greater.obs[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].sid.sat, greater.obs[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].tropo_std, greater.obs[2].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].flags, greater.obs[3].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].iono_std, greater.obs[3].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].range_std, greater.obs[3].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.code, greater.obs[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].sid.sat, greater.obs[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].tropo_std, greater.obs[3].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].flags, greater.obs[4].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].iono_std, greater.obs[4].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].range_std, greater.obs[4].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.code, greater.obs[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].sid.sat, greater.obs[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].tropo_std, greater.obs[4].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].flags, greater.obs[5].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].iono_std, greater.obs[5].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].range_std, greater.obs[5].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.code, greater.obs[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].sid.sat, greater.obs[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].tropo_std, greater.obs[5].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.f, greater.obs[6].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.i, greater.obs[6].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].P, greater.obs[6].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].flags, greater.obs[6].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].iono_std, greater.obs[6].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].lock, greater.obs[6].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].range_std, greater.obs[6].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].sid.code, greater.obs[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].sid.sat, greater.obs[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].tropo_std, greater.obs[6].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].L.f, greater.obs[7].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].L.i, greater.obs[7].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].P, greater.obs[7].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].flags, greater.obs[7].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].iono_std, greater.obs[7].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].lock, greater.obs[7].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].range_std, greater.obs[7].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].sid.code, greater.obs[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].sid.sat, greater.obs[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[7].tropo_std, greater.obs[7].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].L.f, greater.obs[8].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].L.i, greater.obs[8].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].P, greater.obs[8].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].flags, greater.obs[8].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].iono_std, greater.obs[8].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].lock, greater.obs[8].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].range_std, greater.obs[8].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].sid.code, greater.obs[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].sid.sat, greater.obs[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[8].tropo_std, greater.obs[8].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].L.f, greater.obs[9].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].L.i, greater.obs[9].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].P, greater.obs[9].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].flags, greater.obs[9].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].iono_std, greater.obs[9].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].lock, greater.obs[9].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].range_std, greater.obs[9].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].sid.code, greater.obs[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].sid.sat, greater.obs[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[9].tropo_std, greater.obs[9].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].L.f, greater.obs[10].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].L.i, greater.obs[10].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].P, greater.obs[10].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].flags, greater.obs[10].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].iono_std, greater.obs[10].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].lock, greater.obs[10].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].range_std, greater.obs[10].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].sid.code, greater.obs[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].sid.sat, greater.obs[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[10].tropo_std, greater.obs[10].tropo_std); + comparison_tests(lesser, greater); + } + + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].L.f, greater.obs[11].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].L.i, greater.obs[11].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].P, greater.obs[11].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].flags, greater.obs[11].flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].iono_std, greater.obs[11].iono_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].lock, greater.obs[11].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].range_std, greater.obs[11].range_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].sid.code, greater.obs[11].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].sid.sat, greater.obs[11].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_osr_t lesser = info.test_msg; + sbp_msg_osr_t greater = info.test_msg; + make_lesser_greater(lesser.obs[11].tropo_std, greater.obs[11].tropo_std); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgOsr); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OSR"); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_osr_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_osr_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - sbp_msg_osr_t test_msg{}; - test_msg.header.n_obs = 64; - test_msg.header.t.ns_residual = 0; - test_msg.header.t.tow = 501867000; - test_msg.header.t.wn = 2152; - test_msg.n_obs = 12; - - test_msg.obs[0].L.f = 66; - test_msg.obs[0].L.i = 121567974; - test_msg.obs[0].P = 1156681547; - test_msg.obs[0].flags = 3; - test_msg.obs[0].iono_std = 13; - test_msg.obs[0].lock = 15; - test_msg.obs[0].range_std = 7; - test_msg.obs[0].sid.code = 0; - test_msg.obs[0].sid.sat = 1; - test_msg.obs[0].tropo_std = 7; - - test_msg.obs[1].L.f = 75; - test_msg.obs[1].L.i = 111817196; - test_msg.obs[1].P = 1063905486; - test_msg.obs[1].flags = 3; - test_msg.obs[1].iono_std = 13; - test_msg.obs[1].lock = 15; - test_msg.obs[1].range_std = 3; - test_msg.obs[1].sid.code = 0; - test_msg.obs[1].sid.sat = 13; - test_msg.obs[1].tropo_std = 3; - - test_msg.obs[2].L.f = 128; - test_msg.obs[2].L.i = 110692129; - test_msg.obs[2].P = 1053200685; - test_msg.obs[2].flags = 3; - test_msg.obs[2].iono_std = 13; - test_msg.obs[2].lock = 15; - test_msg.obs[2].range_std = 3; - test_msg.obs[2].sid.code = 0; - test_msg.obs[2].sid.sat = 14; - test_msg.obs[2].tropo_std = 3; - - test_msg.obs[3].L.f = 127; - test_msg.obs[3].L.i = 119549583; - test_msg.obs[3].P = 1137476697; - test_msg.obs[3].flags = 3; - test_msg.obs[3].iono_std = 13; - test_msg.obs[3].lock = 15; - test_msg.obs[3].range_std = 5; - test_msg.obs[3].sid.code = 0; - test_msg.obs[3].sid.sat = 15; - test_msg.obs[3].tropo_std = 5; - - test_msg.obs[4].L.f = 55; - test_msg.obs[4].L.i = 106934294; - test_msg.obs[4].P = 1017446132; - test_msg.obs[4].flags = 3; - test_msg.obs[4].iono_std = 0; - test_msg.obs[4].lock = 15; - test_msg.obs[4].range_std = 2; - test_msg.obs[4].sid.code = 0; - test_msg.obs[4].sid.sat = 17; - test_msg.obs[4].tropo_std = 2; - - test_msg.obs[5].L.f = 108; - test_msg.obs[5].L.i = 110024343; - test_msg.obs[5].P = 1046846826; - test_msg.obs[5].flags = 3; - test_msg.obs[5].iono_std = 13; - test_msg.obs[5].lock = 15; - test_msg.obs[5].range_std = 3; - test_msg.obs[5].sid.code = 0; - test_msg.obs[5].sid.sat = 19; - test_msg.obs[5].tropo_std = 3; - - test_msg.obs[6].L.f = 206; - test_msg.obs[6].L.i = 111507381; - test_msg.obs[6].P = 1060957521; - test_msg.obs[6].flags = 3; - test_msg.obs[6].iono_std = 13; - test_msg.obs[6].lock = 15; - test_msg.obs[6].range_std = 3; - test_msg.obs[6].sid.code = 0; - test_msg.obs[6].sid.sat = 28; - test_msg.obs[6].tropo_std = 3; - - test_msg.obs[7].L.f = 200; - test_msg.obs[7].L.i = 113614775; - test_msg.obs[7].P = 1081009286; - test_msg.obs[7].flags = 3; - test_msg.obs[7].iono_std = 13; - test_msg.obs[7].lock = 15; - test_msg.obs[7].range_std = 3; - test_msg.obs[7].sid.code = 0; - test_msg.obs[7].sid.sat = 30; - test_msg.obs[7].tropo_std = 3; - - test_msg.obs[8].L.f = 170; - test_msg.obs[8].L.i = 94728270; - test_msg.obs[8].P = 1156681781; - test_msg.obs[8].flags = 3; - test_msg.obs[8].iono_std = 21; - test_msg.obs[8].lock = 15; - test_msg.obs[8].range_std = 7; - test_msg.obs[8].sid.code = 6; - test_msg.obs[8].sid.sat = 1; - test_msg.obs[8].tropo_std = 7; - - test_msg.obs[9].L.f = 129; - test_msg.obs[9].L.i = 87130275; - test_msg.obs[9].P = 1063905531; - test_msg.obs[9].flags = 3; - test_msg.obs[9].iono_std = 21; - test_msg.obs[9].lock = 15; - test_msg.obs[9].range_std = 3; - test_msg.obs[9].sid.code = 6; - test_msg.obs[9].sid.sat = 13; - test_msg.obs[9].tropo_std = 3; - - test_msg.obs[10].L.f = 46; - test_msg.obs[10].L.i = 86253605; - test_msg.obs[10].P = 1053200752; - test_msg.obs[10].flags = 3; - test_msg.obs[10].iono_std = 21; - test_msg.obs[10].lock = 15; - test_msg.obs[10].range_std = 3; - test_msg.obs[10].sid.code = 6; - test_msg.obs[10].sid.sat = 14; - test_msg.obs[10].tropo_std = 3; - - test_msg.obs[11].L.f = 95; - test_msg.obs[11].L.i = 93155512; - test_msg.obs[11].P = 1137476774; - test_msg.obs[11].flags = 3; - test_msg.obs[11].iono_std = 21; - test_msg.obs[11].lock = 15; - test_msg.obs[11].range_std = 5; - test_msg.obs[11].sid.code = 6; - test_msg.obs[11].sid.sat = 15; - test_msg.obs[11].tropo_std = 5; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 64) - << "incorrect value for last_msg_.header.n_obs, expected 64, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.ns_residual, 0) - << "incorrect value for last_msg_.header.t.ns_residual, expected 0, is " - << last_msg_.header.t.ns_residual; - EXPECT_EQ(last_msg_.header.t.tow, 501867000) - << "incorrect value for last_msg_.header.t.tow, expected 501867000, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 2152) - << "incorrect value for last_msg_.header.t.wn, expected 2152, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 12) - << "incorrect value for last_msg_.n_obs, expected 12, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 66) - << "incorrect value for last_msg_.obs[0].L.f, expected 66, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 121567974) - << "incorrect value for last_msg_.obs[0].L.i, expected 121567974, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1156681547) - << "incorrect value for last_msg_.obs[0].P, expected 1156681547, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].flags, 3) - << "incorrect value for last_msg_.obs[0].flags, expected 3, is " - << last_msg_.obs[0].flags; - EXPECT_EQ(last_msg_.obs[0].iono_std, 13) - << "incorrect value for last_msg_.obs[0].iono_std, expected 13, is " - << last_msg_.obs[0].iono_std; - EXPECT_EQ(last_msg_.obs[0].lock, 15) - << "incorrect value for last_msg_.obs[0].lock, expected 15, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].range_std, 7) - << "incorrect value for last_msg_.obs[0].range_std, expected 7, is " - << last_msg_.obs[0].range_std; - EXPECT_EQ(last_msg_.obs[0].sid.code, 0) - << "incorrect value for last_msg_.obs[0].sid.code, expected 0, is " - << last_msg_.obs[0].sid.code; - EXPECT_EQ(last_msg_.obs[0].sid.sat, 1) - << "incorrect value for last_msg_.obs[0].sid.sat, expected 1, is " - << last_msg_.obs[0].sid.sat; - EXPECT_EQ(last_msg_.obs[0].tropo_std, 7) - << "incorrect value for last_msg_.obs[0].tropo_std, expected 7, is " - << last_msg_.obs[0].tropo_std; - EXPECT_EQ(last_msg_.obs[1].L.f, 75) - << "incorrect value for last_msg_.obs[1].L.f, expected 75, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 111817196) - << "incorrect value for last_msg_.obs[1].L.i, expected 111817196, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 1063905486) - << "incorrect value for last_msg_.obs[1].P, expected 1063905486, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].flags, 3) - << "incorrect value for last_msg_.obs[1].flags, expected 3, is " - << last_msg_.obs[1].flags; - EXPECT_EQ(last_msg_.obs[1].iono_std, 13) - << "incorrect value for last_msg_.obs[1].iono_std, expected 13, is " - << last_msg_.obs[1].iono_std; - EXPECT_EQ(last_msg_.obs[1].lock, 15) - << "incorrect value for last_msg_.obs[1].lock, expected 15, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].range_std, 3) - << "incorrect value for last_msg_.obs[1].range_std, expected 3, is " - << last_msg_.obs[1].range_std; - EXPECT_EQ(last_msg_.obs[1].sid.code, 0) - << "incorrect value for last_msg_.obs[1].sid.code, expected 0, is " - << last_msg_.obs[1].sid.code; - EXPECT_EQ(last_msg_.obs[1].sid.sat, 13) - << "incorrect value for last_msg_.obs[1].sid.sat, expected 13, is " - << last_msg_.obs[1].sid.sat; - EXPECT_EQ(last_msg_.obs[1].tropo_std, 3) - << "incorrect value for last_msg_.obs[1].tropo_std, expected 3, is " - << last_msg_.obs[1].tropo_std; - EXPECT_EQ(last_msg_.obs[2].L.f, 128) - << "incorrect value for last_msg_.obs[2].L.f, expected 128, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, 110692129) - << "incorrect value for last_msg_.obs[2].L.i, expected 110692129, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 1053200685) - << "incorrect value for last_msg_.obs[2].P, expected 1053200685, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].flags, 3) - << "incorrect value for last_msg_.obs[2].flags, expected 3, is " - << last_msg_.obs[2].flags; - EXPECT_EQ(last_msg_.obs[2].iono_std, 13) - << "incorrect value for last_msg_.obs[2].iono_std, expected 13, is " - << last_msg_.obs[2].iono_std; - EXPECT_EQ(last_msg_.obs[2].lock, 15) - << "incorrect value for last_msg_.obs[2].lock, expected 15, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].range_std, 3) - << "incorrect value for last_msg_.obs[2].range_std, expected 3, is " - << last_msg_.obs[2].range_std; - EXPECT_EQ(last_msg_.obs[2].sid.code, 0) - << "incorrect value for last_msg_.obs[2].sid.code, expected 0, is " - << last_msg_.obs[2].sid.code; - EXPECT_EQ(last_msg_.obs[2].sid.sat, 14) - << "incorrect value for last_msg_.obs[2].sid.sat, expected 14, is " - << last_msg_.obs[2].sid.sat; - EXPECT_EQ(last_msg_.obs[2].tropo_std, 3) - << "incorrect value for last_msg_.obs[2].tropo_std, expected 3, is " - << last_msg_.obs[2].tropo_std; - EXPECT_EQ(last_msg_.obs[3].L.f, 127) - << "incorrect value for last_msg_.obs[3].L.f, expected 127, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 119549583) - << "incorrect value for last_msg_.obs[3].L.i, expected 119549583, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 1137476697) - << "incorrect value for last_msg_.obs[3].P, expected 1137476697, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].flags, 3) - << "incorrect value for last_msg_.obs[3].flags, expected 3, is " - << last_msg_.obs[3].flags; - EXPECT_EQ(last_msg_.obs[3].iono_std, 13) - << "incorrect value for last_msg_.obs[3].iono_std, expected 13, is " - << last_msg_.obs[3].iono_std; - EXPECT_EQ(last_msg_.obs[3].lock, 15) - << "incorrect value for last_msg_.obs[3].lock, expected 15, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].range_std, 5) - << "incorrect value for last_msg_.obs[3].range_std, expected 5, is " - << last_msg_.obs[3].range_std; - EXPECT_EQ(last_msg_.obs[3].sid.code, 0) - << "incorrect value for last_msg_.obs[3].sid.code, expected 0, is " - << last_msg_.obs[3].sid.code; - EXPECT_EQ(last_msg_.obs[3].sid.sat, 15) - << "incorrect value for last_msg_.obs[3].sid.sat, expected 15, is " - << last_msg_.obs[3].sid.sat; - EXPECT_EQ(last_msg_.obs[3].tropo_std, 5) - << "incorrect value for last_msg_.obs[3].tropo_std, expected 5, is " - << last_msg_.obs[3].tropo_std; - EXPECT_EQ(last_msg_.obs[4].L.f, 55) - << "incorrect value for last_msg_.obs[4].L.f, expected 55, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, 106934294) - << "incorrect value for last_msg_.obs[4].L.i, expected 106934294, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1017446132) - << "incorrect value for last_msg_.obs[4].P, expected 1017446132, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].flags, 3) - << "incorrect value for last_msg_.obs[4].flags, expected 3, is " - << last_msg_.obs[4].flags; - EXPECT_EQ(last_msg_.obs[4].iono_std, 0) - << "incorrect value for last_msg_.obs[4].iono_std, expected 0, is " - << last_msg_.obs[4].iono_std; - EXPECT_EQ(last_msg_.obs[4].lock, 15) - << "incorrect value for last_msg_.obs[4].lock, expected 15, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].range_std, 2) - << "incorrect value for last_msg_.obs[4].range_std, expected 2, is " - << last_msg_.obs[4].range_std; - EXPECT_EQ(last_msg_.obs[4].sid.code, 0) - << "incorrect value for last_msg_.obs[4].sid.code, expected 0, is " - << last_msg_.obs[4].sid.code; - EXPECT_EQ(last_msg_.obs[4].sid.sat, 17) - << "incorrect value for last_msg_.obs[4].sid.sat, expected 17, is " - << last_msg_.obs[4].sid.sat; - EXPECT_EQ(last_msg_.obs[4].tropo_std, 2) - << "incorrect value for last_msg_.obs[4].tropo_std, expected 2, is " - << last_msg_.obs[4].tropo_std; - EXPECT_EQ(last_msg_.obs[5].L.f, 108) - << "incorrect value for last_msg_.obs[5].L.f, expected 108, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 110024343) - << "incorrect value for last_msg_.obs[5].L.i, expected 110024343, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 1046846826) - << "incorrect value for last_msg_.obs[5].P, expected 1046846826, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].flags, 3) - << "incorrect value for last_msg_.obs[5].flags, expected 3, is " - << last_msg_.obs[5].flags; - EXPECT_EQ(last_msg_.obs[5].iono_std, 13) - << "incorrect value for last_msg_.obs[5].iono_std, expected 13, is " - << last_msg_.obs[5].iono_std; - EXPECT_EQ(last_msg_.obs[5].lock, 15) - << "incorrect value for last_msg_.obs[5].lock, expected 15, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].range_std, 3) - << "incorrect value for last_msg_.obs[5].range_std, expected 3, is " - << last_msg_.obs[5].range_std; - EXPECT_EQ(last_msg_.obs[5].sid.code, 0) - << "incorrect value for last_msg_.obs[5].sid.code, expected 0, is " - << last_msg_.obs[5].sid.code; - EXPECT_EQ(last_msg_.obs[5].sid.sat, 19) - << "incorrect value for last_msg_.obs[5].sid.sat, expected 19, is " - << last_msg_.obs[5].sid.sat; - EXPECT_EQ(last_msg_.obs[5].tropo_std, 3) - << "incorrect value for last_msg_.obs[5].tropo_std, expected 3, is " - << last_msg_.obs[5].tropo_std; - EXPECT_EQ(last_msg_.obs[6].L.f, 206) - << "incorrect value for last_msg_.obs[6].L.f, expected 206, is " - << last_msg_.obs[6].L.f; - EXPECT_EQ(last_msg_.obs[6].L.i, 111507381) - << "incorrect value for last_msg_.obs[6].L.i, expected 111507381, is " - << last_msg_.obs[6].L.i; - EXPECT_EQ(last_msg_.obs[6].P, 1060957521) - << "incorrect value for last_msg_.obs[6].P, expected 1060957521, is " - << last_msg_.obs[6].P; - EXPECT_EQ(last_msg_.obs[6].flags, 3) - << "incorrect value for last_msg_.obs[6].flags, expected 3, is " - << last_msg_.obs[6].flags; - EXPECT_EQ(last_msg_.obs[6].iono_std, 13) - << "incorrect value for last_msg_.obs[6].iono_std, expected 13, is " - << last_msg_.obs[6].iono_std; - EXPECT_EQ(last_msg_.obs[6].lock, 15) - << "incorrect value for last_msg_.obs[6].lock, expected 15, is " - << last_msg_.obs[6].lock; - EXPECT_EQ(last_msg_.obs[6].range_std, 3) - << "incorrect value for last_msg_.obs[6].range_std, expected 3, is " - << last_msg_.obs[6].range_std; - EXPECT_EQ(last_msg_.obs[6].sid.code, 0) - << "incorrect value for last_msg_.obs[6].sid.code, expected 0, is " - << last_msg_.obs[6].sid.code; - EXPECT_EQ(last_msg_.obs[6].sid.sat, 28) - << "incorrect value for last_msg_.obs[6].sid.sat, expected 28, is " - << last_msg_.obs[6].sid.sat; - EXPECT_EQ(last_msg_.obs[6].tropo_std, 3) - << "incorrect value for last_msg_.obs[6].tropo_std, expected 3, is " - << last_msg_.obs[6].tropo_std; - EXPECT_EQ(last_msg_.obs[7].L.f, 200) - << "incorrect value for last_msg_.obs[7].L.f, expected 200, is " - << last_msg_.obs[7].L.f; - EXPECT_EQ(last_msg_.obs[7].L.i, 113614775) - << "incorrect value for last_msg_.obs[7].L.i, expected 113614775, is " - << last_msg_.obs[7].L.i; - EXPECT_EQ(last_msg_.obs[7].P, 1081009286) - << "incorrect value for last_msg_.obs[7].P, expected 1081009286, is " - << last_msg_.obs[7].P; - EXPECT_EQ(last_msg_.obs[7].flags, 3) - << "incorrect value for last_msg_.obs[7].flags, expected 3, is " - << last_msg_.obs[7].flags; - EXPECT_EQ(last_msg_.obs[7].iono_std, 13) - << "incorrect value for last_msg_.obs[7].iono_std, expected 13, is " - << last_msg_.obs[7].iono_std; - EXPECT_EQ(last_msg_.obs[7].lock, 15) - << "incorrect value for last_msg_.obs[7].lock, expected 15, is " - << last_msg_.obs[7].lock; - EXPECT_EQ(last_msg_.obs[7].range_std, 3) - << "incorrect value for last_msg_.obs[7].range_std, expected 3, is " - << last_msg_.obs[7].range_std; - EXPECT_EQ(last_msg_.obs[7].sid.code, 0) - << "incorrect value for last_msg_.obs[7].sid.code, expected 0, is " - << last_msg_.obs[7].sid.code; - EXPECT_EQ(last_msg_.obs[7].sid.sat, 30) - << "incorrect value for last_msg_.obs[7].sid.sat, expected 30, is " - << last_msg_.obs[7].sid.sat; - EXPECT_EQ(last_msg_.obs[7].tropo_std, 3) - << "incorrect value for last_msg_.obs[7].tropo_std, expected 3, is " - << last_msg_.obs[7].tropo_std; - EXPECT_EQ(last_msg_.obs[8].L.f, 170) - << "incorrect value for last_msg_.obs[8].L.f, expected 170, is " - << last_msg_.obs[8].L.f; - EXPECT_EQ(last_msg_.obs[8].L.i, 94728270) - << "incorrect value for last_msg_.obs[8].L.i, expected 94728270, is " - << last_msg_.obs[8].L.i; - EXPECT_EQ(last_msg_.obs[8].P, 1156681781) - << "incorrect value for last_msg_.obs[8].P, expected 1156681781, is " - << last_msg_.obs[8].P; - EXPECT_EQ(last_msg_.obs[8].flags, 3) - << "incorrect value for last_msg_.obs[8].flags, expected 3, is " - << last_msg_.obs[8].flags; - EXPECT_EQ(last_msg_.obs[8].iono_std, 21) - << "incorrect value for last_msg_.obs[8].iono_std, expected 21, is " - << last_msg_.obs[8].iono_std; - EXPECT_EQ(last_msg_.obs[8].lock, 15) - << "incorrect value for last_msg_.obs[8].lock, expected 15, is " - << last_msg_.obs[8].lock; - EXPECT_EQ(last_msg_.obs[8].range_std, 7) - << "incorrect value for last_msg_.obs[8].range_std, expected 7, is " - << last_msg_.obs[8].range_std; - EXPECT_EQ(last_msg_.obs[8].sid.code, 6) - << "incorrect value for last_msg_.obs[8].sid.code, expected 6, is " - << last_msg_.obs[8].sid.code; - EXPECT_EQ(last_msg_.obs[8].sid.sat, 1) - << "incorrect value for last_msg_.obs[8].sid.sat, expected 1, is " - << last_msg_.obs[8].sid.sat; - EXPECT_EQ(last_msg_.obs[8].tropo_std, 7) - << "incorrect value for last_msg_.obs[8].tropo_std, expected 7, is " - << last_msg_.obs[8].tropo_std; - EXPECT_EQ(last_msg_.obs[9].L.f, 129) - << "incorrect value for last_msg_.obs[9].L.f, expected 129, is " - << last_msg_.obs[9].L.f; - EXPECT_EQ(last_msg_.obs[9].L.i, 87130275) - << "incorrect value for last_msg_.obs[9].L.i, expected 87130275, is " - << last_msg_.obs[9].L.i; - EXPECT_EQ(last_msg_.obs[9].P, 1063905531) - << "incorrect value for last_msg_.obs[9].P, expected 1063905531, is " - << last_msg_.obs[9].P; - EXPECT_EQ(last_msg_.obs[9].flags, 3) - << "incorrect value for last_msg_.obs[9].flags, expected 3, is " - << last_msg_.obs[9].flags; - EXPECT_EQ(last_msg_.obs[9].iono_std, 21) - << "incorrect value for last_msg_.obs[9].iono_std, expected 21, is " - << last_msg_.obs[9].iono_std; - EXPECT_EQ(last_msg_.obs[9].lock, 15) - << "incorrect value for last_msg_.obs[9].lock, expected 15, is " - << last_msg_.obs[9].lock; - EXPECT_EQ(last_msg_.obs[9].range_std, 3) - << "incorrect value for last_msg_.obs[9].range_std, expected 3, is " - << last_msg_.obs[9].range_std; - EXPECT_EQ(last_msg_.obs[9].sid.code, 6) - << "incorrect value for last_msg_.obs[9].sid.code, expected 6, is " - << last_msg_.obs[9].sid.code; - EXPECT_EQ(last_msg_.obs[9].sid.sat, 13) - << "incorrect value for last_msg_.obs[9].sid.sat, expected 13, is " - << last_msg_.obs[9].sid.sat; - EXPECT_EQ(last_msg_.obs[9].tropo_std, 3) - << "incorrect value for last_msg_.obs[9].tropo_std, expected 3, is " - << last_msg_.obs[9].tropo_std; - EXPECT_EQ(last_msg_.obs[10].L.f, 46) - << "incorrect value for last_msg_.obs[10].L.f, expected 46, is " - << last_msg_.obs[10].L.f; - EXPECT_EQ(last_msg_.obs[10].L.i, 86253605) - << "incorrect value for last_msg_.obs[10].L.i, expected 86253605, is " - << last_msg_.obs[10].L.i; - EXPECT_EQ(last_msg_.obs[10].P, 1053200752) - << "incorrect value for last_msg_.obs[10].P, expected 1053200752, is " - << last_msg_.obs[10].P; - EXPECT_EQ(last_msg_.obs[10].flags, 3) - << "incorrect value for last_msg_.obs[10].flags, expected 3, is " - << last_msg_.obs[10].flags; - EXPECT_EQ(last_msg_.obs[10].iono_std, 21) - << "incorrect value for last_msg_.obs[10].iono_std, expected 21, is " - << last_msg_.obs[10].iono_std; - EXPECT_EQ(last_msg_.obs[10].lock, 15) - << "incorrect value for last_msg_.obs[10].lock, expected 15, is " - << last_msg_.obs[10].lock; - EXPECT_EQ(last_msg_.obs[10].range_std, 3) - << "incorrect value for last_msg_.obs[10].range_std, expected 3, is " - << last_msg_.obs[10].range_std; - EXPECT_EQ(last_msg_.obs[10].sid.code, 6) - << "incorrect value for last_msg_.obs[10].sid.code, expected 6, is " - << last_msg_.obs[10].sid.code; - EXPECT_EQ(last_msg_.obs[10].sid.sat, 14) - << "incorrect value for last_msg_.obs[10].sid.sat, expected 14, is " - << last_msg_.obs[10].sid.sat; - EXPECT_EQ(last_msg_.obs[10].tropo_std, 3) - << "incorrect value for last_msg_.obs[10].tropo_std, expected 3, is " - << last_msg_.obs[10].tropo_std; - EXPECT_EQ(last_msg_.obs[11].L.f, 95) - << "incorrect value for last_msg_.obs[11].L.f, expected 95, is " - << last_msg_.obs[11].L.f; - EXPECT_EQ(last_msg_.obs[11].L.i, 93155512) - << "incorrect value for last_msg_.obs[11].L.i, expected 93155512, is " - << last_msg_.obs[11].L.i; - EXPECT_EQ(last_msg_.obs[11].P, 1137476774) - << "incorrect value for last_msg_.obs[11].P, expected 1137476774, is " - << last_msg_.obs[11].P; - EXPECT_EQ(last_msg_.obs[11].flags, 3) - << "incorrect value for last_msg_.obs[11].flags, expected 3, is " - << last_msg_.obs[11].flags; - EXPECT_EQ(last_msg_.obs[11].iono_std, 21) - << "incorrect value for last_msg_.obs[11].iono_std, expected 21, is " - << last_msg_.obs[11].iono_std; - EXPECT_EQ(last_msg_.obs[11].lock, 15) - << "incorrect value for last_msg_.obs[11].lock, expected 15, is " - << last_msg_.obs[11].lock; - EXPECT_EQ(last_msg_.obs[11].range_std, 5) - << "incorrect value for last_msg_.obs[11].range_std, expected 5, is " - << last_msg_.obs[11].range_std; - EXPECT_EQ(last_msg_.obs[11].sid.code, 6) - << "incorrect value for last_msg_.obs[11].sid.code, expected 6, is " - << last_msg_.obs[11].sid.code; - EXPECT_EQ(last_msg_.obs[11].sid.sat, 15) - << "incorrect value for last_msg_.obs[11].sid.sat, expected 15, is " - << last_msg_.obs[11].sid.sat; - EXPECT_EQ(last_msg_.obs[11].tropo_std, 5) - << "incorrect value for last_msg_.obs[11].tropo_std, expected 5, is " - << last_msg_.obs[11].tropo_std; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.osr, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.osr, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[239]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 239); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 239), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_osr_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 239); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgOsr, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgOsr0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgOsr, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_MsgSvAzEl.cc b/c/test/cpp/auto_check_sbp_observation_MsgSvAzEl.cc index c436c4012b..9c4a8015f3 100644 --- a/c/test/cpp/auto_check_sbp_observation_MsgSvAzEl.cc +++ b/c/test/cpp/auto_check_sbp_observation_MsgSvAzEl.cc @@ -16,66 +16,434 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_MsgSvAzEl0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_MsgSvAzEl0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_MsgSvAzEl0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_MsgSvAzEl0() { + assign(test_msg_.azel[0].az, 160); + assign(test_msg_.azel[0].el, 12); + assign(test_msg_.azel[0].sid.code, 0); + assign(test_msg_.azel[0].sid.sat, 8); + + assign(test_msg_.azel[1].az, 139); + assign(test_msg_.azel[1].el, 66); + assign(test_msg_.azel[1].sid.code, 0); + assign(test_msg_.azel[1].sid.sat, 10); + + assign(test_msg_.azel[2].az, 16); + assign(test_msg_.azel[2].el, 1); + assign(test_msg_.azel[2].sid.code, 0); + assign(test_msg_.azel[2].sid.sat, 13); + + assign(test_msg_.azel[3].az, 24); + assign(test_msg_.azel[3].el, 25); + assign(test_msg_.azel[3].sid.code, 0); + assign(test_msg_.azel[3].sid.sat, 15); + + assign(test_msg_.azel[4].az, 127); + assign(test_msg_.azel[4].el, 18); + assign(test_msg_.azel[4].sid.code, 0); + assign(test_msg_.azel[4].sid.sat, 16); + + assign(test_msg_.azel[5].az, 42); + assign(test_msg_.azel[5].el, 53); + assign(test_msg_.azel[5].sid.code, 0); + assign(test_msg_.azel[5].sid.sat, 18); + + assign(test_msg_.azel[6].az, 31); + assign(test_msg_.azel[6].el, 16); + assign(test_msg_.azel[6].sid.code, 0); + assign(test_msg_.azel[6].sid.sat, 20); + + assign(test_msg_.azel[7].az, 12); + assign(test_msg_.azel[7].el, 67); + assign(test_msg_.azel[7].sid.code, 0); + assign(test_msg_.azel[7].sid.sat, 23); + + assign(test_msg_.azel[8].az, 47); + assign(test_msg_.azel[8].el, 10); + assign(test_msg_.azel[8].sid.code, 0); + assign(test_msg_.azel[8].sid.sat, 24); + + assign(test_msg_.azel[9].az, 116); + assign(test_msg_.azel[9].el, 8); + assign(test_msg_.azel[9].sid.code, 0); + assign(test_msg_.azel[9].sid.sat, 26); + + assign(test_msg_.azel[10].az, 153); + assign(test_msg_.azel[10].el, 43); + assign(test_msg_.azel[10].sid.code, 0); + assign(test_msg_.azel[10].sid.sat, 27); + + assign(test_msg_.azel[11].az, 77); + assign(test_msg_.azel[11].el, 10); + assign(test_msg_.azel[11].sid.code, 0); + assign(test_msg_.azel[11].sid.sat, 29); + + assign(test_msg_.azel[12].az, 94); + assign(test_msg_.azel[12].el, 26); + assign(test_msg_.azel[12].sid.code, 0); + assign(test_msg_.azel[12].sid.sat, 32); + + assign(test_msg_.azel[13].az, 16); + assign(test_msg_.azel[13].el, 58); + assign(test_msg_.azel[13].sid.code, 3); + assign(test_msg_.azel[13].sid.sat, 1); + + assign(test_msg_.azel[14].az, 108); + assign(test_msg_.azel[14].el, 53); + assign(test_msg_.azel[14].sid.code, 3); + assign(test_msg_.azel[14].sid.sat, 2); + + assign(test_msg_.azel[15].az, 17); + assign(test_msg_.azel[15].el, 13); + assign(test_msg_.azel[15].sid.code, 3); + assign(test_msg_.azel[15].sid.sat, 8); + + assign(test_msg_.azel[16].az, 165); + assign(test_msg_.azel[16].el, 40); + assign(test_msg_.azel[16].sid.code, 3); + assign(test_msg_.azel[16].sid.sat, 17); + + assign(test_msg_.azel[17].az, 63); + assign(test_msg_.azel[17].el, 35); + assign(test_msg_.azel[17].sid.code, 3); + assign(test_msg_.azel[17].sid.sat, 23); + + assign(test_msg_.azel[18].az, 41); + assign(test_msg_.azel[18].el, 73); + assign(test_msg_.azel[18].sid.code, 3); + assign(test_msg_.azel[18].sid.sat, 24); + + assign(test_msg_.azel[19].az, 114); + assign(test_msg_.azel[19].el, 26); + assign(test_msg_.azel[19].sid.code, 12); + assign(test_msg_.azel[19].sid.sat, 20); + + assign(test_msg_.azel[20].az, 72); + assign(test_msg_.azel[20].el, 54); + assign(test_msg_.azel[20].sid.code, 12); + assign(test_msg_.azel[20].sid.sat, 27); + + assign(test_msg_.azel[21].az, 69); + assign(test_msg_.azel[21].el, 3); + assign(test_msg_.azel[21].sid.code, 12); + assign(test_msg_.azel[21].sid.sat, 28); + + assign(test_msg_.azel[22].az, 158); + assign(test_msg_.azel[22].el, 14); + assign(test_msg_.azel[22].sid.code, 12); + assign(test_msg_.azel[22].sid.sat, 29); + + assign(test_msg_.azel[23].az, 152); + assign(test_msg_.azel[23].el, 68); + assign(test_msg_.azel[23].sid.code, 12); + assign(test_msg_.azel[23].sid.sat, 30); + + assign(test_msg_.azel[24].az, 120); + assign(test_msg_.azel[24].el, 82); + assign(test_msg_.azel[24].sid.code, 12); + assign(test_msg_.azel[24].sid.sat, 32); + + assign(test_msg_.azel[25].az, 131); + assign(test_msg_.azel[25].el, 6); + assign(test_msg_.azel[25].sid.code, 14); + assign(test_msg_.azel[25].sid.sat, 2); + + assign(test_msg_.azel[26].az, 27); + assign(test_msg_.azel[26].el, 44); + assign(test_msg_.azel[26].sid.code, 14); + assign(test_msg_.azel[26].sid.sat, 4); + + assign(test_msg_.azel[27].az, 101); + assign(test_msg_.azel[27].el, 21); + assign(test_msg_.azel[27].sid.code, 14); + assign(test_msg_.azel[27].sid.sat, 5); + + assign(test_msg_.azel[28].az, 81); + assign(test_msg_.azel[28].el, 65); + assign(test_msg_.azel[28].sid.code, 14); + assign(test_msg_.azel[28].sid.sat, 9); + + assign(test_msg_.azel[29].az, 49); + assign(test_msg_.azel[29].el, 56); + assign(test_msg_.azel[29].sid.code, 14); + assign(test_msg_.azel[29].sid.sat, 11); + + assign(test_msg_.azel[30].az, 59); + assign(test_msg_.azel[30].el, 6); + assign(test_msg_.azel[30].sid.code, 14); + assign(test_msg_.azel[30].sid.sat, 12); + + assign(test_msg_.azel[31].az, 154); + assign(test_msg_.azel[31].el, 4); + assign(test_msg_.azel[31].sid.code, 14); + assign(test_msg_.azel[31].sid.sat, 30); + + assign(test_msg_.azel[32].az, 165); + assign(test_msg_.azel[32].el, 62); + assign(test_msg_.azel[32].sid.code, 14); + assign(test_msg_.azel[32].sid.sat, 36); + assign(test_msg_.n_azel, 33); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_sv_az_el_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_sv_az_el_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSvAzEl, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_sv_az_el_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSvAzEl); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->sv_az_el, sizeof(msg->sv_az_el)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_sv_az_el_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.sv_az_el, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSvAzEl); + info.sender_id = 31183; + info.preamble = 0x55; + info.crc = 0x24A8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 132; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_sv_az_el_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_sv_az_el_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_sv_az_el_t &lesser, + const sbp_msg_sv_az_el_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_sv_az_el_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_sv_az_el_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_sv_az_el_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_sv_az_el_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSvAzEl, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSvAzEl, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSvAzEl, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSvAzEl, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_MsgSvAzEl0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_sv_az_el_t test_msg_{}; + uint8_t encoded_frame_[132 + 8] = { 85, 151, 0, 207, 121, 132, 8, 0, 160, 12, 10, 0, 139, 66, 13, 0, 16, 1, 15, 0, 24, 25, 16, 0, 127, 18, 18, 0, 42, 53, 20, 0, 31, 16, 23, 0, 12, 67, 24, 0, 47, 10, 26, 0, 116, 8, 27, 0, @@ -86,584 +454,1140 @@ TEST_F(Test_auto_check_sbp_observation_MsgSvAzEl0, Test) { 27, 44, 5, 14, 101, 21, 9, 14, 81, 65, 11, 14, 49, 56, 12, 14, 59, 6, 30, 14, 154, 4, 36, 14, 165, 62, 168, 36, }; + uint8_t encoded_payload_[132] = { + 8, 0, 160, 12, 10, 0, 139, 66, 13, 0, 16, 1, 15, 0, 24, + 25, 16, 0, 127, 18, 18, 0, 42, 53, 20, 0, 31, 16, 23, 0, + 12, 67, 24, 0, 47, 10, 26, 0, 116, 8, 27, 0, 153, 43, 29, + 0, 77, 10, 32, 0, 94, 26, 1, 3, 16, 58, 2, 3, 108, 53, + 8, 3, 17, 13, 17, 3, 165, 40, 23, 3, 63, 35, 24, 3, 41, + 73, 20, 12, 114, 26, 27, 12, 72, 54, 28, 12, 69, 3, 29, 12, + 158, 14, 30, 12, 152, 68, 32, 12, 120, 82, 2, 14, 131, 6, 4, + 14, 27, 44, 5, 14, 101, 21, 9, 14, 81, 65, 11, 14, 49, 56, + 12, 14, 59, 6, 30, 14, 154, 4, 36, 14, 165, 62, + }; +}; + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_sv_az_el_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSvAzEl, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[132]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_sv_az_el_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 132); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 132), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgSvAzEl, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 132); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 132), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[132]; + + EXPECT_EQ( + sbp_msg_sv_az_el_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 132), 0); +} +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[132]; + + for (uint8_t i = 0; i < 132; i++) { + EXPECT_EQ(sbp_msg_sv_az_el_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sv_az_el_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_sv_az_el_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 132); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSvAzEl, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 132); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_sv_az_el_t msg{}; - sbp_msg_sv_az_el_t test_msg{}; - - test_msg.azel[0].az = 160; - test_msg.azel[0].el = 12; - test_msg.azel[0].sid.code = 0; - test_msg.azel[0].sid.sat = 8; - - test_msg.azel[1].az = 139; - test_msg.azel[1].el = 66; - test_msg.azel[1].sid.code = 0; - test_msg.azel[1].sid.sat = 10; - - test_msg.azel[2].az = 16; - test_msg.azel[2].el = 1; - test_msg.azel[2].sid.code = 0; - test_msg.azel[2].sid.sat = 13; - - test_msg.azel[3].az = 24; - test_msg.azel[3].el = 25; - test_msg.azel[3].sid.code = 0; - test_msg.azel[3].sid.sat = 15; - - test_msg.azel[4].az = 127; - test_msg.azel[4].el = 18; - test_msg.azel[4].sid.code = 0; - test_msg.azel[4].sid.sat = 16; - - test_msg.azel[5].az = 42; - test_msg.azel[5].el = 53; - test_msg.azel[5].sid.code = 0; - test_msg.azel[5].sid.sat = 18; - - test_msg.azel[6].az = 31; - test_msg.azel[6].el = 16; - test_msg.azel[6].sid.code = 0; - test_msg.azel[6].sid.sat = 20; - - test_msg.azel[7].az = 12; - test_msg.azel[7].el = 67; - test_msg.azel[7].sid.code = 0; - test_msg.azel[7].sid.sat = 23; - - test_msg.azel[8].az = 47; - test_msg.azel[8].el = 10; - test_msg.azel[8].sid.code = 0; - test_msg.azel[8].sid.sat = 24; - - test_msg.azel[9].az = 116; - test_msg.azel[9].el = 8; - test_msg.azel[9].sid.code = 0; - test_msg.azel[9].sid.sat = 26; - - test_msg.azel[10].az = 153; - test_msg.azel[10].el = 43; - test_msg.azel[10].sid.code = 0; - test_msg.azel[10].sid.sat = 27; - - test_msg.azel[11].az = 77; - test_msg.azel[11].el = 10; - test_msg.azel[11].sid.code = 0; - test_msg.azel[11].sid.sat = 29; - - test_msg.azel[12].az = 94; - test_msg.azel[12].el = 26; - test_msg.azel[12].sid.code = 0; - test_msg.azel[12].sid.sat = 32; - - test_msg.azel[13].az = 16; - test_msg.azel[13].el = 58; - test_msg.azel[13].sid.code = 3; - test_msg.azel[13].sid.sat = 1; - - test_msg.azel[14].az = 108; - test_msg.azel[14].el = 53; - test_msg.azel[14].sid.code = 3; - test_msg.azel[14].sid.sat = 2; - - test_msg.azel[15].az = 17; - test_msg.azel[15].el = 13; - test_msg.azel[15].sid.code = 3; - test_msg.azel[15].sid.sat = 8; - - test_msg.azel[16].az = 165; - test_msg.azel[16].el = 40; - test_msg.azel[16].sid.code = 3; - test_msg.azel[16].sid.sat = 17; - - test_msg.azel[17].az = 63; - test_msg.azel[17].el = 35; - test_msg.azel[17].sid.code = 3; - test_msg.azel[17].sid.sat = 23; - - test_msg.azel[18].az = 41; - test_msg.azel[18].el = 73; - test_msg.azel[18].sid.code = 3; - test_msg.azel[18].sid.sat = 24; - - test_msg.azel[19].az = 114; - test_msg.azel[19].el = 26; - test_msg.azel[19].sid.code = 12; - test_msg.azel[19].sid.sat = 20; - - test_msg.azel[20].az = 72; - test_msg.azel[20].el = 54; - test_msg.azel[20].sid.code = 12; - test_msg.azel[20].sid.sat = 27; - - test_msg.azel[21].az = 69; - test_msg.azel[21].el = 3; - test_msg.azel[21].sid.code = 12; - test_msg.azel[21].sid.sat = 28; - - test_msg.azel[22].az = 158; - test_msg.azel[22].el = 14; - test_msg.azel[22].sid.code = 12; - test_msg.azel[22].sid.sat = 29; - - test_msg.azel[23].az = 152; - test_msg.azel[23].el = 68; - test_msg.azel[23].sid.code = 12; - test_msg.azel[23].sid.sat = 30; - - test_msg.azel[24].az = 120; - test_msg.azel[24].el = 82; - test_msg.azel[24].sid.code = 12; - test_msg.azel[24].sid.sat = 32; - - test_msg.azel[25].az = 131; - test_msg.azel[25].el = 6; - test_msg.azel[25].sid.code = 14; - test_msg.azel[25].sid.sat = 2; - - test_msg.azel[26].az = 27; - test_msg.azel[26].el = 44; - test_msg.azel[26].sid.code = 14; - test_msg.azel[26].sid.sat = 4; - - test_msg.azel[27].az = 101; - test_msg.azel[27].el = 21; - test_msg.azel[27].sid.code = 14; - test_msg.azel[27].sid.sat = 5; - - test_msg.azel[28].az = 81; - test_msg.azel[28].el = 65; - test_msg.azel[28].sid.code = 14; - test_msg.azel[28].sid.sat = 9; - - test_msg.azel[29].az = 49; - test_msg.azel[29].el = 56; - test_msg.azel[29].sid.code = 14; - test_msg.azel[29].sid.sat = 11; - - test_msg.azel[30].az = 59; - test_msg.azel[30].el = 6; - test_msg.azel[30].sid.code = 14; - test_msg.azel[30].sid.sat = 12; - - test_msg.azel[31].az = 154; - test_msg.azel[31].el = 4; - test_msg.azel[31].sid.code = 14; - test_msg.azel[31].sid.sat = 30; - - test_msg.azel[32].az = 165; - test_msg.azel[32].el = 62; - test_msg.azel[32].sid.code = 14; - test_msg.azel[32].sid.sat = 36; - test_msg.n_azel = 33; - - EXPECT_EQ(send_message(31183, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 31183); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.azel[0].az, 160) - << "incorrect value for last_msg_.azel[0].az, expected 160, is " - << last_msg_.azel[0].az; - EXPECT_EQ(last_msg_.azel[0].el, 12) - << "incorrect value for last_msg_.azel[0].el, expected 12, is " - << last_msg_.azel[0].el; - EXPECT_EQ(last_msg_.azel[0].sid.code, 0) - << "incorrect value for last_msg_.azel[0].sid.code, expected 0, is " - << last_msg_.azel[0].sid.code; - EXPECT_EQ(last_msg_.azel[0].sid.sat, 8) - << "incorrect value for last_msg_.azel[0].sid.sat, expected 8, is " - << last_msg_.azel[0].sid.sat; - EXPECT_EQ(last_msg_.azel[1].az, 139) - << "incorrect value for last_msg_.azel[1].az, expected 139, is " - << last_msg_.azel[1].az; - EXPECT_EQ(last_msg_.azel[1].el, 66) - << "incorrect value for last_msg_.azel[1].el, expected 66, is " - << last_msg_.azel[1].el; - EXPECT_EQ(last_msg_.azel[1].sid.code, 0) - << "incorrect value for last_msg_.azel[1].sid.code, expected 0, is " - << last_msg_.azel[1].sid.code; - EXPECT_EQ(last_msg_.azel[1].sid.sat, 10) - << "incorrect value for last_msg_.azel[1].sid.sat, expected 10, is " - << last_msg_.azel[1].sid.sat; - EXPECT_EQ(last_msg_.azel[2].az, 16) - << "incorrect value for last_msg_.azel[2].az, expected 16, is " - << last_msg_.azel[2].az; - EXPECT_EQ(last_msg_.azel[2].el, 1) - << "incorrect value for last_msg_.azel[2].el, expected 1, is " - << last_msg_.azel[2].el; - EXPECT_EQ(last_msg_.azel[2].sid.code, 0) - << "incorrect value for last_msg_.azel[2].sid.code, expected 0, is " - << last_msg_.azel[2].sid.code; - EXPECT_EQ(last_msg_.azel[2].sid.sat, 13) - << "incorrect value for last_msg_.azel[2].sid.sat, expected 13, is " - << last_msg_.azel[2].sid.sat; - EXPECT_EQ(last_msg_.azel[3].az, 24) - << "incorrect value for last_msg_.azel[3].az, expected 24, is " - << last_msg_.azel[3].az; - EXPECT_EQ(last_msg_.azel[3].el, 25) - << "incorrect value for last_msg_.azel[3].el, expected 25, is " - << last_msg_.azel[3].el; - EXPECT_EQ(last_msg_.azel[3].sid.code, 0) - << "incorrect value for last_msg_.azel[3].sid.code, expected 0, is " - << last_msg_.azel[3].sid.code; - EXPECT_EQ(last_msg_.azel[3].sid.sat, 15) - << "incorrect value for last_msg_.azel[3].sid.sat, expected 15, is " - << last_msg_.azel[3].sid.sat; - EXPECT_EQ(last_msg_.azel[4].az, 127) - << "incorrect value for last_msg_.azel[4].az, expected 127, is " - << last_msg_.azel[4].az; - EXPECT_EQ(last_msg_.azel[4].el, 18) - << "incorrect value for last_msg_.azel[4].el, expected 18, is " - << last_msg_.azel[4].el; - EXPECT_EQ(last_msg_.azel[4].sid.code, 0) - << "incorrect value for last_msg_.azel[4].sid.code, expected 0, is " - << last_msg_.azel[4].sid.code; - EXPECT_EQ(last_msg_.azel[4].sid.sat, 16) - << "incorrect value for last_msg_.azel[4].sid.sat, expected 16, is " - << last_msg_.azel[4].sid.sat; - EXPECT_EQ(last_msg_.azel[5].az, 42) - << "incorrect value for last_msg_.azel[5].az, expected 42, is " - << last_msg_.azel[5].az; - EXPECT_EQ(last_msg_.azel[5].el, 53) - << "incorrect value for last_msg_.azel[5].el, expected 53, is " - << last_msg_.azel[5].el; - EXPECT_EQ(last_msg_.azel[5].sid.code, 0) - << "incorrect value for last_msg_.azel[5].sid.code, expected 0, is " - << last_msg_.azel[5].sid.code; - EXPECT_EQ(last_msg_.azel[5].sid.sat, 18) - << "incorrect value for last_msg_.azel[5].sid.sat, expected 18, is " - << last_msg_.azel[5].sid.sat; - EXPECT_EQ(last_msg_.azel[6].az, 31) - << "incorrect value for last_msg_.azel[6].az, expected 31, is " - << last_msg_.azel[6].az; - EXPECT_EQ(last_msg_.azel[6].el, 16) - << "incorrect value for last_msg_.azel[6].el, expected 16, is " - << last_msg_.azel[6].el; - EXPECT_EQ(last_msg_.azel[6].sid.code, 0) - << "incorrect value for last_msg_.azel[6].sid.code, expected 0, is " - << last_msg_.azel[6].sid.code; - EXPECT_EQ(last_msg_.azel[6].sid.sat, 20) - << "incorrect value for last_msg_.azel[6].sid.sat, expected 20, is " - << last_msg_.azel[6].sid.sat; - EXPECT_EQ(last_msg_.azel[7].az, 12) - << "incorrect value for last_msg_.azel[7].az, expected 12, is " - << last_msg_.azel[7].az; - EXPECT_EQ(last_msg_.azel[7].el, 67) - << "incorrect value for last_msg_.azel[7].el, expected 67, is " - << last_msg_.azel[7].el; - EXPECT_EQ(last_msg_.azel[7].sid.code, 0) - << "incorrect value for last_msg_.azel[7].sid.code, expected 0, is " - << last_msg_.azel[7].sid.code; - EXPECT_EQ(last_msg_.azel[7].sid.sat, 23) - << "incorrect value for last_msg_.azel[7].sid.sat, expected 23, is " - << last_msg_.azel[7].sid.sat; - EXPECT_EQ(last_msg_.azel[8].az, 47) - << "incorrect value for last_msg_.azel[8].az, expected 47, is " - << last_msg_.azel[8].az; - EXPECT_EQ(last_msg_.azel[8].el, 10) - << "incorrect value for last_msg_.azel[8].el, expected 10, is " - << last_msg_.azel[8].el; - EXPECT_EQ(last_msg_.azel[8].sid.code, 0) - << "incorrect value for last_msg_.azel[8].sid.code, expected 0, is " - << last_msg_.azel[8].sid.code; - EXPECT_EQ(last_msg_.azel[8].sid.sat, 24) - << "incorrect value for last_msg_.azel[8].sid.sat, expected 24, is " - << last_msg_.azel[8].sid.sat; - EXPECT_EQ(last_msg_.azel[9].az, 116) - << "incorrect value for last_msg_.azel[9].az, expected 116, is " - << last_msg_.azel[9].az; - EXPECT_EQ(last_msg_.azel[9].el, 8) - << "incorrect value for last_msg_.azel[9].el, expected 8, is " - << last_msg_.azel[9].el; - EXPECT_EQ(last_msg_.azel[9].sid.code, 0) - << "incorrect value for last_msg_.azel[9].sid.code, expected 0, is " - << last_msg_.azel[9].sid.code; - EXPECT_EQ(last_msg_.azel[9].sid.sat, 26) - << "incorrect value for last_msg_.azel[9].sid.sat, expected 26, is " - << last_msg_.azel[9].sid.sat; - EXPECT_EQ(last_msg_.azel[10].az, 153) - << "incorrect value for last_msg_.azel[10].az, expected 153, is " - << last_msg_.azel[10].az; - EXPECT_EQ(last_msg_.azel[10].el, 43) - << "incorrect value for last_msg_.azel[10].el, expected 43, is " - << last_msg_.azel[10].el; - EXPECT_EQ(last_msg_.azel[10].sid.code, 0) - << "incorrect value for last_msg_.azel[10].sid.code, expected 0, is " - << last_msg_.azel[10].sid.code; - EXPECT_EQ(last_msg_.azel[10].sid.sat, 27) - << "incorrect value for last_msg_.azel[10].sid.sat, expected 27, is " - << last_msg_.azel[10].sid.sat; - EXPECT_EQ(last_msg_.azel[11].az, 77) - << "incorrect value for last_msg_.azel[11].az, expected 77, is " - << last_msg_.azel[11].az; - EXPECT_EQ(last_msg_.azel[11].el, 10) - << "incorrect value for last_msg_.azel[11].el, expected 10, is " - << last_msg_.azel[11].el; - EXPECT_EQ(last_msg_.azel[11].sid.code, 0) - << "incorrect value for last_msg_.azel[11].sid.code, expected 0, is " - << last_msg_.azel[11].sid.code; - EXPECT_EQ(last_msg_.azel[11].sid.sat, 29) - << "incorrect value for last_msg_.azel[11].sid.sat, expected 29, is " - << last_msg_.azel[11].sid.sat; - EXPECT_EQ(last_msg_.azel[12].az, 94) - << "incorrect value for last_msg_.azel[12].az, expected 94, is " - << last_msg_.azel[12].az; - EXPECT_EQ(last_msg_.azel[12].el, 26) - << "incorrect value for last_msg_.azel[12].el, expected 26, is " - << last_msg_.azel[12].el; - EXPECT_EQ(last_msg_.azel[12].sid.code, 0) - << "incorrect value for last_msg_.azel[12].sid.code, expected 0, is " - << last_msg_.azel[12].sid.code; - EXPECT_EQ(last_msg_.azel[12].sid.sat, 32) - << "incorrect value for last_msg_.azel[12].sid.sat, expected 32, is " - << last_msg_.azel[12].sid.sat; - EXPECT_EQ(last_msg_.azel[13].az, 16) - << "incorrect value for last_msg_.azel[13].az, expected 16, is " - << last_msg_.azel[13].az; - EXPECT_EQ(last_msg_.azel[13].el, 58) - << "incorrect value for last_msg_.azel[13].el, expected 58, is " - << last_msg_.azel[13].el; - EXPECT_EQ(last_msg_.azel[13].sid.code, 3) - << "incorrect value for last_msg_.azel[13].sid.code, expected 3, is " - << last_msg_.azel[13].sid.code; - EXPECT_EQ(last_msg_.azel[13].sid.sat, 1) - << "incorrect value for last_msg_.azel[13].sid.sat, expected 1, is " - << last_msg_.azel[13].sid.sat; - EXPECT_EQ(last_msg_.azel[14].az, 108) - << "incorrect value for last_msg_.azel[14].az, expected 108, is " - << last_msg_.azel[14].az; - EXPECT_EQ(last_msg_.azel[14].el, 53) - << "incorrect value for last_msg_.azel[14].el, expected 53, is " - << last_msg_.azel[14].el; - EXPECT_EQ(last_msg_.azel[14].sid.code, 3) - << "incorrect value for last_msg_.azel[14].sid.code, expected 3, is " - << last_msg_.azel[14].sid.code; - EXPECT_EQ(last_msg_.azel[14].sid.sat, 2) - << "incorrect value for last_msg_.azel[14].sid.sat, expected 2, is " - << last_msg_.azel[14].sid.sat; - EXPECT_EQ(last_msg_.azel[15].az, 17) - << "incorrect value for last_msg_.azel[15].az, expected 17, is " - << last_msg_.azel[15].az; - EXPECT_EQ(last_msg_.azel[15].el, 13) - << "incorrect value for last_msg_.azel[15].el, expected 13, is " - << last_msg_.azel[15].el; - EXPECT_EQ(last_msg_.azel[15].sid.code, 3) - << "incorrect value for last_msg_.azel[15].sid.code, expected 3, is " - << last_msg_.azel[15].sid.code; - EXPECT_EQ(last_msg_.azel[15].sid.sat, 8) - << "incorrect value for last_msg_.azel[15].sid.sat, expected 8, is " - << last_msg_.azel[15].sid.sat; - EXPECT_EQ(last_msg_.azel[16].az, 165) - << "incorrect value for last_msg_.azel[16].az, expected 165, is " - << last_msg_.azel[16].az; - EXPECT_EQ(last_msg_.azel[16].el, 40) - << "incorrect value for last_msg_.azel[16].el, expected 40, is " - << last_msg_.azel[16].el; - EXPECT_EQ(last_msg_.azel[16].sid.code, 3) - << "incorrect value for last_msg_.azel[16].sid.code, expected 3, is " - << last_msg_.azel[16].sid.code; - EXPECT_EQ(last_msg_.azel[16].sid.sat, 17) - << "incorrect value for last_msg_.azel[16].sid.sat, expected 17, is " - << last_msg_.azel[16].sid.sat; - EXPECT_EQ(last_msg_.azel[17].az, 63) - << "incorrect value for last_msg_.azel[17].az, expected 63, is " - << last_msg_.azel[17].az; - EXPECT_EQ(last_msg_.azel[17].el, 35) - << "incorrect value for last_msg_.azel[17].el, expected 35, is " - << last_msg_.azel[17].el; - EXPECT_EQ(last_msg_.azel[17].sid.code, 3) - << "incorrect value for last_msg_.azel[17].sid.code, expected 3, is " - << last_msg_.azel[17].sid.code; - EXPECT_EQ(last_msg_.azel[17].sid.sat, 23) - << "incorrect value for last_msg_.azel[17].sid.sat, expected 23, is " - << last_msg_.azel[17].sid.sat; - EXPECT_EQ(last_msg_.azel[18].az, 41) - << "incorrect value for last_msg_.azel[18].az, expected 41, is " - << last_msg_.azel[18].az; - EXPECT_EQ(last_msg_.azel[18].el, 73) - << "incorrect value for last_msg_.azel[18].el, expected 73, is " - << last_msg_.azel[18].el; - EXPECT_EQ(last_msg_.azel[18].sid.code, 3) - << "incorrect value for last_msg_.azel[18].sid.code, expected 3, is " - << last_msg_.azel[18].sid.code; - EXPECT_EQ(last_msg_.azel[18].sid.sat, 24) - << "incorrect value for last_msg_.azel[18].sid.sat, expected 24, is " - << last_msg_.azel[18].sid.sat; - EXPECT_EQ(last_msg_.azel[19].az, 114) - << "incorrect value for last_msg_.azel[19].az, expected 114, is " - << last_msg_.azel[19].az; - EXPECT_EQ(last_msg_.azel[19].el, 26) - << "incorrect value for last_msg_.azel[19].el, expected 26, is " - << last_msg_.azel[19].el; - EXPECT_EQ(last_msg_.azel[19].sid.code, 12) - << "incorrect value for last_msg_.azel[19].sid.code, expected 12, is " - << last_msg_.azel[19].sid.code; - EXPECT_EQ(last_msg_.azel[19].sid.sat, 20) - << "incorrect value for last_msg_.azel[19].sid.sat, expected 20, is " - << last_msg_.azel[19].sid.sat; - EXPECT_EQ(last_msg_.azel[20].az, 72) - << "incorrect value for last_msg_.azel[20].az, expected 72, is " - << last_msg_.azel[20].az; - EXPECT_EQ(last_msg_.azel[20].el, 54) - << "incorrect value for last_msg_.azel[20].el, expected 54, is " - << last_msg_.azel[20].el; - EXPECT_EQ(last_msg_.azel[20].sid.code, 12) - << "incorrect value for last_msg_.azel[20].sid.code, expected 12, is " - << last_msg_.azel[20].sid.code; - EXPECT_EQ(last_msg_.azel[20].sid.sat, 27) - << "incorrect value for last_msg_.azel[20].sid.sat, expected 27, is " - << last_msg_.azel[20].sid.sat; - EXPECT_EQ(last_msg_.azel[21].az, 69) - << "incorrect value for last_msg_.azel[21].az, expected 69, is " - << last_msg_.azel[21].az; - EXPECT_EQ(last_msg_.azel[21].el, 3) - << "incorrect value for last_msg_.azel[21].el, expected 3, is " - << last_msg_.azel[21].el; - EXPECT_EQ(last_msg_.azel[21].sid.code, 12) - << "incorrect value for last_msg_.azel[21].sid.code, expected 12, is " - << last_msg_.azel[21].sid.code; - EXPECT_EQ(last_msg_.azel[21].sid.sat, 28) - << "incorrect value for last_msg_.azel[21].sid.sat, expected 28, is " - << last_msg_.azel[21].sid.sat; - EXPECT_EQ(last_msg_.azel[22].az, 158) - << "incorrect value for last_msg_.azel[22].az, expected 158, is " - << last_msg_.azel[22].az; - EXPECT_EQ(last_msg_.azel[22].el, 14) - << "incorrect value for last_msg_.azel[22].el, expected 14, is " - << last_msg_.azel[22].el; - EXPECT_EQ(last_msg_.azel[22].sid.code, 12) - << "incorrect value for last_msg_.azel[22].sid.code, expected 12, is " - << last_msg_.azel[22].sid.code; - EXPECT_EQ(last_msg_.azel[22].sid.sat, 29) - << "incorrect value for last_msg_.azel[22].sid.sat, expected 29, is " - << last_msg_.azel[22].sid.sat; - EXPECT_EQ(last_msg_.azel[23].az, 152) - << "incorrect value for last_msg_.azel[23].az, expected 152, is " - << last_msg_.azel[23].az; - EXPECT_EQ(last_msg_.azel[23].el, 68) - << "incorrect value for last_msg_.azel[23].el, expected 68, is " - << last_msg_.azel[23].el; - EXPECT_EQ(last_msg_.azel[23].sid.code, 12) - << "incorrect value for last_msg_.azel[23].sid.code, expected 12, is " - << last_msg_.azel[23].sid.code; - EXPECT_EQ(last_msg_.azel[23].sid.sat, 30) - << "incorrect value for last_msg_.azel[23].sid.sat, expected 30, is " - << last_msg_.azel[23].sid.sat; - EXPECT_EQ(last_msg_.azel[24].az, 120) - << "incorrect value for last_msg_.azel[24].az, expected 120, is " - << last_msg_.azel[24].az; - EXPECT_EQ(last_msg_.azel[24].el, 82) - << "incorrect value for last_msg_.azel[24].el, expected 82, is " - << last_msg_.azel[24].el; - EXPECT_EQ(last_msg_.azel[24].sid.code, 12) - << "incorrect value for last_msg_.azel[24].sid.code, expected 12, is " - << last_msg_.azel[24].sid.code; - EXPECT_EQ(last_msg_.azel[24].sid.sat, 32) - << "incorrect value for last_msg_.azel[24].sid.sat, expected 32, is " - << last_msg_.azel[24].sid.sat; - EXPECT_EQ(last_msg_.azel[25].az, 131) - << "incorrect value for last_msg_.azel[25].az, expected 131, is " - << last_msg_.azel[25].az; - EXPECT_EQ(last_msg_.azel[25].el, 6) - << "incorrect value for last_msg_.azel[25].el, expected 6, is " - << last_msg_.azel[25].el; - EXPECT_EQ(last_msg_.azel[25].sid.code, 14) - << "incorrect value for last_msg_.azel[25].sid.code, expected 14, is " - << last_msg_.azel[25].sid.code; - EXPECT_EQ(last_msg_.azel[25].sid.sat, 2) - << "incorrect value for last_msg_.azel[25].sid.sat, expected 2, is " - << last_msg_.azel[25].sid.sat; - EXPECT_EQ(last_msg_.azel[26].az, 27) - << "incorrect value for last_msg_.azel[26].az, expected 27, is " - << last_msg_.azel[26].az; - EXPECT_EQ(last_msg_.azel[26].el, 44) - << "incorrect value for last_msg_.azel[26].el, expected 44, is " - << last_msg_.azel[26].el; - EXPECT_EQ(last_msg_.azel[26].sid.code, 14) - << "incorrect value for last_msg_.azel[26].sid.code, expected 14, is " - << last_msg_.azel[26].sid.code; - EXPECT_EQ(last_msg_.azel[26].sid.sat, 4) - << "incorrect value for last_msg_.azel[26].sid.sat, expected 4, is " - << last_msg_.azel[26].sid.sat; - EXPECT_EQ(last_msg_.azel[27].az, 101) - << "incorrect value for last_msg_.azel[27].az, expected 101, is " - << last_msg_.azel[27].az; - EXPECT_EQ(last_msg_.azel[27].el, 21) - << "incorrect value for last_msg_.azel[27].el, expected 21, is " - << last_msg_.azel[27].el; - EXPECT_EQ(last_msg_.azel[27].sid.code, 14) - << "incorrect value for last_msg_.azel[27].sid.code, expected 14, is " - << last_msg_.azel[27].sid.code; - EXPECT_EQ(last_msg_.azel[27].sid.sat, 5) - << "incorrect value for last_msg_.azel[27].sid.sat, expected 5, is " - << last_msg_.azel[27].sid.sat; - EXPECT_EQ(last_msg_.azel[28].az, 81) - << "incorrect value for last_msg_.azel[28].az, expected 81, is " - << last_msg_.azel[28].az; - EXPECT_EQ(last_msg_.azel[28].el, 65) - << "incorrect value for last_msg_.azel[28].el, expected 65, is " - << last_msg_.azel[28].el; - EXPECT_EQ(last_msg_.azel[28].sid.code, 14) - << "incorrect value for last_msg_.azel[28].sid.code, expected 14, is " - << last_msg_.azel[28].sid.code; - EXPECT_EQ(last_msg_.azel[28].sid.sat, 9) - << "incorrect value for last_msg_.azel[28].sid.sat, expected 9, is " - << last_msg_.azel[28].sid.sat; - EXPECT_EQ(last_msg_.azel[29].az, 49) - << "incorrect value for last_msg_.azel[29].az, expected 49, is " - << last_msg_.azel[29].az; - EXPECT_EQ(last_msg_.azel[29].el, 56) - << "incorrect value for last_msg_.azel[29].el, expected 56, is " - << last_msg_.azel[29].el; - EXPECT_EQ(last_msg_.azel[29].sid.code, 14) - << "incorrect value for last_msg_.azel[29].sid.code, expected 14, is " - << last_msg_.azel[29].sid.code; - EXPECT_EQ(last_msg_.azel[29].sid.sat, 11) - << "incorrect value for last_msg_.azel[29].sid.sat, expected 11, is " - << last_msg_.azel[29].sid.sat; - EXPECT_EQ(last_msg_.azel[30].az, 59) - << "incorrect value for last_msg_.azel[30].az, expected 59, is " - << last_msg_.azel[30].az; - EXPECT_EQ(last_msg_.azel[30].el, 6) - << "incorrect value for last_msg_.azel[30].el, expected 6, is " - << last_msg_.azel[30].el; - EXPECT_EQ(last_msg_.azel[30].sid.code, 14) - << "incorrect value for last_msg_.azel[30].sid.code, expected 14, is " - << last_msg_.azel[30].sid.code; - EXPECT_EQ(last_msg_.azel[30].sid.sat, 12) - << "incorrect value for last_msg_.azel[30].sid.sat, expected 12, is " - << last_msg_.azel[30].sid.sat; - EXPECT_EQ(last_msg_.azel[31].az, 154) - << "incorrect value for last_msg_.azel[31].az, expected 154, is " - << last_msg_.azel[31].az; - EXPECT_EQ(last_msg_.azel[31].el, 4) - << "incorrect value for last_msg_.azel[31].el, expected 4, is " - << last_msg_.azel[31].el; - EXPECT_EQ(last_msg_.azel[31].sid.code, 14) - << "incorrect value for last_msg_.azel[31].sid.code, expected 14, is " - << last_msg_.azel[31].sid.code; - EXPECT_EQ(last_msg_.azel[31].sid.sat, 30) - << "incorrect value for last_msg_.azel[31].sid.sat, expected 30, is " - << last_msg_.azel[31].sid.sat; - EXPECT_EQ(last_msg_.azel[32].az, 165) - << "incorrect value for last_msg_.azel[32].az, expected 165, is " - << last_msg_.azel[32].az; - EXPECT_EQ(last_msg_.azel[32].el, 62) - << "incorrect value for last_msg_.azel[32].el, expected 62, is " - << last_msg_.azel[32].el; - EXPECT_EQ(last_msg_.azel[32].sid.code, 14) - << "incorrect value for last_msg_.azel[32].sid.code, expected 14, is " - << last_msg_.azel[32].sid.code; - EXPECT_EQ(last_msg_.azel[32].sid.sat, 36) - << "incorrect value for last_msg_.azel[32].sid.sat, expected 36, is " - << last_msg_.azel[32].sid.sat; - EXPECT_EQ(last_msg_.n_azel, 33) - << "incorrect value for last_msg_.n_azel, expected 33, is " - << last_msg_.n_azel; + EXPECT_EQ(sbp_msg_sv_az_el_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_sv_az_el_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_sv_az_el_t t{}; + return sbp_msg_sv_az_el_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_sv_az_el_t t{}; + t.n_azel = 1; + return sbp_msg_sv_az_el_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_sv_az_el_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_sv_az_el_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSvAzEl, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[0].az, greater.azel[0].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[0].el, greater.azel[0].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[0].sid.code, greater.azel[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[0].sid.sat, greater.azel[0].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[1].az, greater.azel[1].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[1].el, greater.azel[1].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[1].sid.code, greater.azel[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[1].sid.sat, greater.azel[1].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[2].az, greater.azel[2].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[2].el, greater.azel[2].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[2].sid.code, greater.azel[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[2].sid.sat, greater.azel[2].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[3].az, greater.azel[3].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[3].el, greater.azel[3].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[3].sid.code, greater.azel[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[3].sid.sat, greater.azel[3].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[4].az, greater.azel[4].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[4].el, greater.azel[4].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[4].sid.code, greater.azel[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[4].sid.sat, greater.azel[4].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[5].az, greater.azel[5].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[5].el, greater.azel[5].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[5].sid.code, greater.azel[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[5].sid.sat, greater.azel[5].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[6].az, greater.azel[6].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[6].el, greater.azel[6].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[6].sid.code, greater.azel[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[6].sid.sat, greater.azel[6].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[7].az, greater.azel[7].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[7].el, greater.azel[7].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[7].sid.code, greater.azel[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[7].sid.sat, greater.azel[7].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[8].az, greater.azel[8].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[8].el, greater.azel[8].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[8].sid.code, greater.azel[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[8].sid.sat, greater.azel[8].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[9].az, greater.azel[9].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[9].el, greater.azel[9].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[9].sid.code, greater.azel[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[9].sid.sat, greater.azel[9].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[10].az, greater.azel[10].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[10].el, greater.azel[10].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[10].sid.code, greater.azel[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[10].sid.sat, greater.azel[10].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[11].az, greater.azel[11].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[11].el, greater.azel[11].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[11].sid.code, greater.azel[11].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[11].sid.sat, greater.azel[11].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[12].az, greater.azel[12].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[12].el, greater.azel[12].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[12].sid.code, greater.azel[12].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[12].sid.sat, greater.azel[12].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[13].az, greater.azel[13].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[13].el, greater.azel[13].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[13].sid.code, greater.azel[13].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[13].sid.sat, greater.azel[13].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[14].az, greater.azel[14].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[14].el, greater.azel[14].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[14].sid.code, greater.azel[14].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[14].sid.sat, greater.azel[14].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[15].az, greater.azel[15].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[15].el, greater.azel[15].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[15].sid.code, greater.azel[15].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[15].sid.sat, greater.azel[15].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[16].az, greater.azel[16].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[16].el, greater.azel[16].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[16].sid.code, greater.azel[16].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[16].sid.sat, greater.azel[16].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[17].az, greater.azel[17].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[17].el, greater.azel[17].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[17].sid.code, greater.azel[17].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[17].sid.sat, greater.azel[17].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[18].az, greater.azel[18].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[18].el, greater.azel[18].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[18].sid.code, greater.azel[18].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[18].sid.sat, greater.azel[18].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[19].az, greater.azel[19].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[19].el, greater.azel[19].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[19].sid.code, greater.azel[19].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[19].sid.sat, greater.azel[19].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[20].az, greater.azel[20].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[20].el, greater.azel[20].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[20].sid.code, greater.azel[20].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[20].sid.sat, greater.azel[20].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[21].az, greater.azel[21].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[21].el, greater.azel[21].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[21].sid.code, greater.azel[21].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[21].sid.sat, greater.azel[21].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[22].az, greater.azel[22].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[22].el, greater.azel[22].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[22].sid.code, greater.azel[22].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[22].sid.sat, greater.azel[22].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[23].az, greater.azel[23].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[23].el, greater.azel[23].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[23].sid.code, greater.azel[23].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[23].sid.sat, greater.azel[23].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[24].az, greater.azel[24].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[24].el, greater.azel[24].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[24].sid.code, greater.azel[24].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[24].sid.sat, greater.azel[24].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[25].az, greater.azel[25].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[25].el, greater.azel[25].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[25].sid.code, greater.azel[25].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[25].sid.sat, greater.azel[25].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[26].az, greater.azel[26].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[26].el, greater.azel[26].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[26].sid.code, greater.azel[26].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[26].sid.sat, greater.azel[26].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[27].az, greater.azel[27].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[27].el, greater.azel[27].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[27].sid.code, greater.azel[27].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[27].sid.sat, greater.azel[27].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[28].az, greater.azel[28].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[28].el, greater.azel[28].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[28].sid.code, greater.azel[28].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[28].sid.sat, greater.azel[28].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[29].az, greater.azel[29].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[29].el, greater.azel[29].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[29].sid.code, greater.azel[29].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[29].sid.sat, greater.azel[29].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[30].az, greater.azel[30].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[30].el, greater.azel[30].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[30].sid.code, greater.azel[30].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[30].sid.sat, greater.azel[30].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[31].az, greater.azel[31].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[31].el, greater.azel[31].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[31].sid.code, greater.azel[31].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[31].sid.sat, greater.azel[31].sid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[32].az, greater.azel[32].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[32].el, greater.azel[32].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[32].sid.code, greater.azel[32].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.azel[32].sid.sat, greater.azel[32].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_sv_az_el_t lesser = info.test_msg; + sbp_msg_sv_az_el_t greater = info.test_msg; + make_lesser_greater(lesser.n_azel, greater.n_azel); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgSvAzEl); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_SV_AZ_EL"); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_sv_az_el_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_sv_az_el_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.sv_az_el, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.sv_az_el, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[132]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 132); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 132), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sv_az_el_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 132); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSvAzEl, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_MsgSvAzEl0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgSvAzEl, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_msgEphemerisDepB.cc b/c/test/cpp/auto_check_sbp_observation_msgEphemerisDepB.cc index 98c5d06bb1..140912f51d 100644 --- a/c/test/cpp/auto_check_sbp_observation_msgEphemerisDepB.cc +++ b/c/test/cpp/auto_check_sbp_observation_msgEphemerisDepB.cc @@ -16,66 +16,304 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_msgEphemerisDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_msgEphemerisDepB0 + : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgEphemerisDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgEphemerisDepB0() { + assign(test_msg_.af0, -1.035025343298912e-05); + assign(test_msg_.af1, -9.094947017729282e-13); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, 6.332993507385254e-08); + assign(test_msg_.c_is, -1.564621925354004e-07); + assign(test_msg_.c_rc, 234.375); + assign(test_msg_.c_rs, -74.90625); + assign(test_msg_.c_uc, -3.937631845474243e-06); + assign(test_msg_.c_us, 6.9122761487960815e-06); + assign(test_msg_.dn, 4.8884179079418005e-09); + assign(test_msg_.ecc, 0.011132609914056957); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9395524830579087); + assign(test_msg_.inc_dot, -3.296565886629854e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, 2.467348395627239); + assign(test_msg_.omega0, -0.9468985437479658); + assign(test_msg_.omegadot, -8.201055892610478e-09); + assign(test_msg_.prn, 3); + assign(test_msg_.sqrta, 5153.714303970337); + assign(test_msg_.tgd, -6.51925802230835e-09); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, 1.0525047200405302); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x9ce1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 60, 190, 0, 0, 0, 0, 0, 186, 82, 192, 0, 0, 0, 0, 0, 76, 109, 64, 0, 0, 0, 0, 0, 132, 208, 190, 0, 0, 0, 0, 0, 254, 220, @@ -90,580 +328,764 @@ TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB0, Test) { 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, 3, 0, 225, 156, }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 0, 60, 190, 0, 0, 0, 0, 0, 186, 82, + 192, 0, 0, 0, 0, 0, 76, 109, 64, 0, 0, 0, 0, 0, 132, + 208, 190, 0, 0, 0, 0, 0, 254, 220, 62, 0, 0, 0, 0, 0, + 0, 113, 62, 0, 0, 0, 0, 0, 0, 133, 190, 28, 36, 25, 81, + 223, 254, 52, 62, 220, 116, 216, 39, 33, 189, 3, 64, 0, 0, 0, + 156, 177, 204, 134, 63, 0, 0, 160, 220, 182, 33, 180, 64, 152, 225, + 192, 44, 254, 76, 238, 191, 41, 150, 24, 2, 148, 156, 65, 190, 252, + 90, 119, 48, 15, 215, 240, 63, 124, 127, 115, 94, 208, 16, 238, 63, + 165, 115, 52, 74, 97, 167, 246, 189, 0, 0, 0, 0, 192, 180, 229, + 190, 0, 0, 0, 0, 0, 0, 112, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 3, 0, + }; +}; - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = -1.035025343298912e-05; - test_msg.af1 = -9.094947017729282e-13; - test_msg.af2 = 0.0; - test_msg.c_ic = 6.332993507385254e-08; - test_msg.c_is = -1.564621925354004e-07; - test_msg.c_rc = 234.375; - test_msg.c_rs = -74.90625; - test_msg.c_uc = -3.937631845474243e-06; - test_msg.c_us = 6.9122761487960815e-06; - test_msg.dn = 4.8884179079418005e-09; - test_msg.ecc = 0.011132609914056957; - test_msg.healthy = 1; - test_msg.inc = 0.9395524830579087; - test_msg.inc_dot = -3.296565886629854e-10; - test_msg.iode = 0; - test_msg.m0 = 2.467348395627239; - test_msg.omega0 = -0.9468985437479658; - test_msg.omegadot = -8.201055892610478e-09; - test_msg.prn = 3; - test_msg.sqrta = 5153.714303970337; - test_msg.tgd = -6.51925802230835e-09; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = 1.0525047200405302; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -1.0350253433e-05 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -1.0350253433e-05, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -9.09494701773e-13 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -9.09494701773e-13, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - 6.33299350739e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected 6.33299350739e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - -1.56462192535e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected -1.56462192535e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 234.375 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 234.375, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - -74.90625 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected -74.90625, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - -3.93763184547e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected -3.93763184547e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 6.9122761488e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 6.9122761488e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 4.88841790794e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 4.88841790794e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.0111326099141 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.0111326099141, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.939552483058 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.939552483058, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - -3.29656588663e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected -3.29656588663e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - 2.46734839563 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected 2.46734839563, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - -0.946898543748 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected -0.946898543748, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.20105589261e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.20105589261e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 3) - << "incorrect value for last_msg_.prn, expected 3, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.71430397 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.71430397, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -6.51925802231e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -6.51925802231e-09, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - 1.05250472004 * 100), 0.05) - << "incorrect value for last_msg_.w, expected 1.05250472004, is " - << last_msg_.w; -} -class Test_auto_check_sbp_observation_msgEphemerisDepB1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgEphemerisDepB1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB1, Test) { - uint8_t encoded_frame[] = { - 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 68, 190, 0, - 0, 0, 0, 0, 72, 66, 64, 0, 0, 0, 0, 128, 188, 115, 64, - 0, 0, 0, 0, 0, 80, 193, 62, 0, 0, 0, 0, 0, 164, 204, - 62, 0, 0, 0, 0, 0, 0, 130, 62, 0, 0, 0, 0, 0, 0, - 128, 62, 72, 181, 127, 6, 208, 225, 52, 62, 158, 174, 129, 91, 27, - 105, 249, 191, 0, 0, 0, 96, 204, 57, 128, 63, 0, 0, 160, 35, - 146, 33, 180, 64, 247, 169, 1, 36, 133, 206, 243, 63, 79, 11, 109, - 92, 156, 208, 65, 190, 103, 78, 3, 253, 223, 147, 255, 191, 164, 214, - 90, 250, 218, 240, 238, 63, 94, 239, 187, 37, 36, 10, 242, 61, 0, - 0, 0, 0, 176, 91, 19, 63, 0, 0, 0, 0, 0, 0, 137, 189, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 12, 25, - 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, - 13, 0, 180, 21, - }; + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = 7.384549826383591e-05; - test_msg.af1 = -2.8421709430404007e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = 1.341104507446289e-07; - test_msg.c_is = 1.1920928955078125e-07; - test_msg.c_rc = 315.78125; - test_msg.c_rs = 36.5625; - test_msg.c_uc = 2.0638108253479004e-06; - test_msg.c_us = 3.4142285585403442e-06; - test_msg.dn = 4.86198823561129e-09; - test_msg.ecc = 0.007922741584479809; - test_msg.healthy = 1; - test_msg.inc = 0.9669012918227122; - test_msg.inc_dot = 2.6251093463412166e-10; - test_msg.iode = 0; - test_msg.m0 = -1.588160855720083; - test_msg.omega0 = 1.237919941568746; - test_msg.omegadot = -8.295702692172441e-09; - test_msg.prn = 13; - test_msg.sqrta = 5153.57085609436; - test_msg.tgd = -9.313225746154785e-09; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = -1.9736022837941165; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - 7.38454982638e-05 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected 7.38454982638e-05, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -2.84217094304e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -2.84217094304e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - 1.34110450745e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected 1.34110450745e-07, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - 1.19209289551e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected 1.19209289551e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 315.78125 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 315.78125, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - 36.5625 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected 36.5625, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - 2.06381082535e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected 2.06381082535e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 3.41422855854e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 3.41422855854e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 4.86198823561e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 4.86198823561e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00792274158448 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00792274158448, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.966901291823 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.966901291823, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - 2.62510934634e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected 2.62510934634e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - -1.58816085572 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected -1.58816085572, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - 1.23791994157 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected 1.23791994157, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.29570269217e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.29570269217e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 13) - << "incorrect value for last_msg_.prn, expected 13, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.57085609 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.57085609, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -9.31322574615e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -9.31322574615e-09, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - -1.97360228379 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -1.97360228379, is " - << last_msg_.w; -} -class Test_auto_check_sbp_observation_msgEphemerisDepB2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgEphemerisDepB1 + : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgEphemerisDepB2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgEphemerisDepB1() { + assign(test_msg_.af0, 7.384549826383591e-05); + assign(test_msg_.af1, -2.8421709430404007e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, 1.341104507446289e-07); + assign(test_msg_.c_is, 1.1920928955078125e-07); + assign(test_msg_.c_rc, 315.78125); + assign(test_msg_.c_rs, 36.5625); + assign(test_msg_.c_uc, 2.0638108253479004e-06); + assign(test_msg_.c_us, 3.4142285585403442e-06); + assign(test_msg_.dn, 4.86198823561129e-09); + assign(test_msg_.ecc, 0.007922741584479809); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9669012918227122); + assign(test_msg_.inc_dot, 2.6251093463412166e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, -1.588160855720083); + assign(test_msg_.omega0, 1.237919941568746); + assign(test_msg_.omegadot, -8.295702692172441e-09); + assign(test_msg_.prn, 13); + assign(test_msg_.sqrta, 5153.57085609436); + assign(test_msg_.tgd, -9.313225746154785e-09); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, -1.9736022837941165); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB2, Test) { - uint8_t encoded_frame[] = { - 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 56, 62, 0, - 0, 0, 0, 0, 40, 81, 192, 0, 0, 0, 0, 0, 129, 109, 64, - 0, 0, 0, 0, 0, 28, 205, 190, 0, 0, 0, 0, 0, 76, 223, - 62, 0, 0, 0, 0, 0, 0, 105, 190, 0, 0, 0, 0, 0, 0, - 92, 190, 134, 161, 223, 255, 243, 43, 51, 62, 146, 176, 113, 142, 234, - 164, 5, 64, 0, 0, 0, 56, 175, 140, 112, 63, 0, 0, 192, 90, - 171, 33, 180, 64, 36, 38, 237, 255, 200, 160, 237, 191, 204, 92, 63, - 154, 49, 91, 65, 190, 125, 94, 251, 132, 52, 61, 216, 63, 2, 139, - 28, 27, 231, 199, 238, 63, 124, 183, 4, 180, 194, 30, 247, 189, 0, - 0, 0, 0, 0, 104, 222, 190, 0, 0, 0, 0, 0, 0, 96, 61, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 12, 25, - 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, - 0, 0, 222, 152, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = -7.249414920806885e-06; - test_msg.af1 = 4.547473508864641e-13; - test_msg.af2 = 0.0; - test_msg.c_ic = -4.6566128730773926e-08; - test_msg.c_is = -2.60770320892334e-08; - test_msg.c_rc = 236.03125; - test_msg.c_rs = -68.625; - test_msg.c_uc = -3.470107913017273e-06; - test_msg.c_us = 7.461756467819214e-06; - test_msg.dn = 4.4637573619826565e-09; - test_msg.ecc = 0.004040417145006359; - test_msg.healthy = 1; - test_msg.inc = 0.9619021920701416; - test_msg.inc_dot = -3.3644258561271105e-10; - test_msg.iode = 0; - test_msg.m0 = 2.7055255058713295; - test_msg.omega0 = -0.9258770941316397; - test_msg.omegadot = -8.082122367123182e-09; - test_msg.prn = 0; - test_msg.sqrta = 5153.669353485107; - test_msg.tgd = 5.587935447692871e-09; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = 0.37873566614641857; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -7.24941492081e-06 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -7.24941492081e-06, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - 4.54747350886e-13 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected 4.54747350886e-13, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - -4.65661287308e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected -4.65661287308e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - -2.60770320892e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected -2.60770320892e-08, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 236.03125 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 236.03125, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - -68.625 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected -68.625, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - -3.47010791302e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected -3.47010791302e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 7.46175646782e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 7.46175646782e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 4.46375736198e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 4.46375736198e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00404041714501 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00404041714501, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.96190219207 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.96190219207, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - -3.36442585613e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected -3.36442585613e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - 2.70552550587 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected 2.70552550587, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - -0.925877094132 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected -0.925877094132, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.08212236712e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.08212236712e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 0) - << "incorrect value for last_msg_.prn, expected 0, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.66935349 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.66935349, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - 5.58793544769e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected 5.58793544769e-09, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - 0.378735666146 * 100), 0.05) - << "incorrect value for last_msg_.w, expected 0.378735666146, is " - << last_msg_.w; -} -class Test_auto_check_sbp_observation_msgEphemerisDepB3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgEphemerisDepB3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x15b4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB3, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 68, 190, 0, 0, 0, 0, 0, 72, 66, 64, 0, 0, 0, 0, 128, 188, 115, 64, 0, 0, 0, 0, 0, 80, 193, 62, 0, 0, 0, 0, 0, 164, 204, @@ -678,384 +1100,3080 @@ TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB3, Test) { 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, 13, 0, 180, 21, }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 0, 68, 190, 0, 0, 0, 0, 0, 72, 66, + 64, 0, 0, 0, 0, 128, 188, 115, 64, 0, 0, 0, 0, 0, 80, + 193, 62, 0, 0, 0, 0, 0, 164, 204, 62, 0, 0, 0, 0, 0, + 0, 130, 62, 0, 0, 0, 0, 0, 0, 128, 62, 72, 181, 127, 6, + 208, 225, 52, 62, 158, 174, 129, 91, 27, 105, 249, 191, 0, 0, 0, + 96, 204, 57, 128, 63, 0, 0, 160, 35, 146, 33, 180, 64, 247, 169, + 1, 36, 133, 206, 243, 63, 79, 11, 109, 92, 156, 208, 65, 190, 103, + 78, 3, 253, 223, 147, 255, 191, 164, 214, 90, 250, 218, 240, 238, 63, + 94, 239, 187, 37, 36, 10, 242, 61, 0, 0, 0, 0, 176, 91, 19, + 63, 0, 0, 0, 0, 0, 0, 137, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 13, 0, + }; +}; - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = 7.384549826383591e-05; - test_msg.af1 = -2.8421709430404007e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = 1.341104507446289e-07; - test_msg.c_is = 1.1920928955078125e-07; - test_msg.c_rc = 315.78125; - test_msg.c_rs = 36.5625; - test_msg.c_uc = 2.0638108253479004e-06; - test_msg.c_us = 3.4142285585403442e-06; - test_msg.dn = 4.86198823561129e-09; - test_msg.ecc = 0.007922741584479809; - test_msg.healthy = 1; - test_msg.inc = 0.9669012918227122; - test_msg.inc_dot = 2.6251093463412166e-10; - test_msg.iode = 0; - test_msg.m0 = -1.588160855720083; - test_msg.omega0 = 1.237919941568746; - test_msg.omegadot = -8.295702692172441e-09; - test_msg.prn = 13; - test_msg.sqrta = 5153.57085609436; - test_msg.tgd = -9.313225746154785e-09; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = -1.9736022837941165; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - 7.38454982638e-05 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected 7.38454982638e-05, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -2.84217094304e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -2.84217094304e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - 1.34110450745e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected 1.34110450745e-07, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - 1.19209289551e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected 1.19209289551e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 315.78125 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 315.78125, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - 36.5625 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected 36.5625, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - 2.06381082535e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected 2.06381082535e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 3.41422855854e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 3.41422855854e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 4.86198823561e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 4.86198823561e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00792274158448 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00792274158448, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.966901291823 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.966901291823, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - 2.62510934634e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected 2.62510934634e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - -1.58816085572 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected -1.58816085572, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - 1.23791994157 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected 1.23791994157, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.29570269217e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.29570269217e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 13) - << "incorrect value for last_msg_.prn, expected 13, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.57085609 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.57085609, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -9.31322574615e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -9.31322574615e-09, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - -1.97360228379 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -1.97360228379, is " - << last_msg_.w; -} -class Test_auto_check_sbp_observation_msgEphemerisDepB4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgEphemerisDepB4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB4, Test) { - uint8_t encoded_frame[] = { - 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 128, 85, 190, 0, - 0, 0, 0, 0, 156, 69, 64, 0, 0, 0, 0, 128, 19, 115, 64, - 0, 0, 0, 0, 0, 160, 193, 62, 0, 0, 0, 0, 0, 152, 207, - 62, 0, 0, 0, 0, 0, 0, 97, 190, 0, 0, 0, 0, 0, 192, - 139, 190, 26, 26, 13, 149, 16, 152, 54, 62, 104, 7, 46, 214, 75, - 84, 5, 192, 0, 0, 0, 128, 230, 82, 132, 63, 0, 0, 160, 252, - 162, 33, 180, 64, 73, 6, 130, 54, 217, 171, 242, 63, 81, 224, 163, - 123, 238, 42, 66, 190, 206, 43, 141, 67, 243, 157, 5, 192, 113, 179, +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgEphemerisDepB2 + : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgEphemerisDepB2() { + assign(test_msg_.af0, -7.249414920806885e-06); + assign(test_msg_.af1, 4.547473508864641e-13); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, -4.6566128730773926e-08); + assign(test_msg_.c_is, -2.60770320892334e-08); + assign(test_msg_.c_rc, 236.03125); + assign(test_msg_.c_rs, -68.625); + assign(test_msg_.c_uc, -3.470107913017273e-06); + assign(test_msg_.c_us, 7.461756467819214e-06); + assign(test_msg_.dn, 4.4637573619826565e-09); + assign(test_msg_.ecc, 0.004040417145006359); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9619021920701416); + assign(test_msg_.inc_dot, -3.3644258561271105e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, 2.7055255058713295); + assign(test_msg_.omega0, -0.9258770941316397); + assign(test_msg_.omegadot, -8.082122367123182e-09); + assign(test_msg_.prn, 0); + assign(test_msg_.sqrta, 5153.669353485107); + assign(test_msg_.tgd, 5.587935447692871e-09); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, 0.37873566614641857); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x98de; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { + 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 56, 62, 0, + 0, 0, 0, 0, 40, 81, 192, 0, 0, 0, 0, 0, 129, 109, 64, + 0, 0, 0, 0, 0, 28, 205, 190, 0, 0, 0, 0, 0, 76, 223, + 62, 0, 0, 0, 0, 0, 0, 105, 190, 0, 0, 0, 0, 0, 0, + 92, 190, 134, 161, 223, 255, 243, 43, 51, 62, 146, 176, 113, 142, 234, + 164, 5, 64, 0, 0, 0, 56, 175, 140, 112, 63, 0, 0, 192, 90, + 171, 33, 180, 64, 36, 38, 237, 255, 200, 160, 237, 191, 204, 92, 63, + 154, 49, 91, 65, 190, 125, 94, 251, 132, 52, 61, 216, 63, 2, 139, + 28, 27, 231, 199, 238, 63, 124, 183, 4, 180, 194, 30, 247, 189, 0, + 0, 0, 0, 0, 104, 222, 190, 0, 0, 0, 0, 0, 0, 96, 61, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 12, 25, + 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, + 0, 0, 222, 152, + }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 0, 56, 62, 0, 0, 0, 0, 0, 40, 81, + 192, 0, 0, 0, 0, 0, 129, 109, 64, 0, 0, 0, 0, 0, 28, + 205, 190, 0, 0, 0, 0, 0, 76, 223, 62, 0, 0, 0, 0, 0, + 0, 105, 190, 0, 0, 0, 0, 0, 0, 92, 190, 134, 161, 223, 255, + 243, 43, 51, 62, 146, 176, 113, 142, 234, 164, 5, 64, 0, 0, 0, + 56, 175, 140, 112, 63, 0, 0, 192, 90, 171, 33, 180, 64, 36, 38, + 237, 255, 200, 160, 237, 191, 204, 92, 63, 154, 49, 91, 65, 190, 125, + 94, 251, 132, 52, 61, 216, 63, 2, 139, 28, 27, 231, 199, 238, 63, + 124, 183, 4, 180, 194, 30, 247, 189, 0, 0, 0, 0, 0, 104, 222, + 190, 0, 0, 0, 0, 0, 0, 96, 61, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgEphemerisDepB3 + : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgEphemerisDepB3() { + assign(test_msg_.af0, 7.384549826383591e-05); + assign(test_msg_.af1, -2.8421709430404007e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, 1.341104507446289e-07); + assign(test_msg_.c_is, 1.1920928955078125e-07); + assign(test_msg_.c_rc, 315.78125); + assign(test_msg_.c_rs, 36.5625); + assign(test_msg_.c_uc, 2.0638108253479004e-06); + assign(test_msg_.c_us, 3.4142285585403442e-06); + assign(test_msg_.dn, 4.86198823561129e-09); + assign(test_msg_.ecc, 0.007922741584479809); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9669012918227122); + assign(test_msg_.inc_dot, 2.6251093463412166e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, -1.588160855720083); + assign(test_msg_.omega0, 1.237919941568746); + assign(test_msg_.omegadot, -8.295702692172441e-09); + assign(test_msg_.prn, 13); + assign(test_msg_.sqrta, 5153.57085609436); + assign(test_msg_.tgd, -9.313225746154785e-09); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, -1.9736022837941165); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x15b4; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { + 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 68, 190, 0, + 0, 0, 0, 0, 72, 66, 64, 0, 0, 0, 0, 128, 188, 115, 64, + 0, 0, 0, 0, 0, 80, 193, 62, 0, 0, 0, 0, 0, 164, 204, + 62, 0, 0, 0, 0, 0, 0, 130, 62, 0, 0, 0, 0, 0, 0, + 128, 62, 72, 181, 127, 6, 208, 225, 52, 62, 158, 174, 129, 91, 27, + 105, 249, 191, 0, 0, 0, 96, 204, 57, 128, 63, 0, 0, 160, 35, + 146, 33, 180, 64, 247, 169, 1, 36, 133, 206, 243, 63, 79, 11, 109, + 92, 156, 208, 65, 190, 103, 78, 3, 253, 223, 147, 255, 191, 164, 214, + 90, 250, 218, 240, 238, 63, 94, 239, 187, 37, 36, 10, 242, 61, 0, + 0, 0, 0, 176, 91, 19, 63, 0, 0, 0, 0, 0, 0, 137, 189, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 12, 25, + 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, + 13, 0, 180, 21, + }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 0, 68, 190, 0, 0, 0, 0, 0, 72, 66, + 64, 0, 0, 0, 0, 128, 188, 115, 64, 0, 0, 0, 0, 0, 80, + 193, 62, 0, 0, 0, 0, 0, 164, 204, 62, 0, 0, 0, 0, 0, + 0, 130, 62, 0, 0, 0, 0, 0, 0, 128, 62, 72, 181, 127, 6, + 208, 225, 52, 62, 158, 174, 129, 91, 27, 105, 249, 191, 0, 0, 0, + 96, 204, 57, 128, 63, 0, 0, 160, 35, 146, 33, 180, 64, 247, 169, + 1, 36, 133, 206, 243, 63, 79, 11, 109, 92, 156, 208, 65, 190, 103, + 78, 3, 253, 223, 147, 255, 191, 164, 214, 90, 250, 218, 240, 238, 63, + 94, 239, 187, 37, 36, 10, 242, 61, 0, 0, 0, 0, 176, 91, 19, + 63, 0, 0, 0, 0, 0, 0, 137, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 13, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgEphemerisDepB4 + : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgEphemerisDepB4() { + assign(test_msg_.af0, -9.925523772835732e-05); + assign(test_msg_.af1, -2.5011104298755527e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, -3.166496753692627e-08); + assign(test_msg_.c_is, -2.0675361156463623e-07); + assign(test_msg_.c_rc, 305.21875); + assign(test_msg_.c_rs, 43.21875); + assign(test_msg_.c_uc, 2.1010637283325195e-06); + assign(test_msg_.c_us, 3.766268491744995e-06); + assign(test_msg_.dn, 5.26057626697412e-09); + assign(test_msg_.ecc, 0.009923744946718216); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9487513221807672); + assign(test_msg_.inc_dot, 3.000124967247105e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, -2.666160271911327); + assign(test_msg_.omega0, 1.1669551972594425); + assign(test_msg_.omegadot, -8.45999524990264e-09); + assign(test_msg_.prn, 22); + assign(test_msg_.sqrta, 5153.636667251587); + assign(test_msg_.tgd, -2.0023435354232788e-08); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, -2.7021241452652935); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x3d63; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { + 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 128, 85, 190, 0, + 0, 0, 0, 0, 156, 69, 64, 0, 0, 0, 0, 128, 19, 115, 64, + 0, 0, 0, 0, 0, 160, 193, 62, 0, 0, 0, 0, 0, 152, 207, + 62, 0, 0, 0, 0, 0, 0, 97, 190, 0, 0, 0, 0, 0, 192, + 139, 190, 26, 26, 13, 149, 16, 152, 54, 62, 104, 7, 46, 214, 75, + 84, 5, 192, 0, 0, 0, 128, 230, 82, 132, 63, 0, 0, 160, 252, + 162, 33, 180, 64, 73, 6, 130, 54, 217, 171, 242, 63, 81, 224, 163, + 123, 238, 42, 66, 190, 206, 43, 141, 67, 243, 157, 5, 192, 113, 179, 153, 187, 43, 92, 238, 63, 254, 236, 31, 43, 224, 157, 244, 61, 0, 0, 0, 0, 232, 4, 26, 191, 0, 0, 0, 0, 0, 0, 134, 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, 22, 0, 99, 61, }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 128, 85, 190, 0, 0, 0, 0, 0, 156, 69, + 64, 0, 0, 0, 0, 128, 19, 115, 64, 0, 0, 0, 0, 0, 160, + 193, 62, 0, 0, 0, 0, 0, 152, 207, 62, 0, 0, 0, 0, 0, + 0, 97, 190, 0, 0, 0, 0, 0, 192, 139, 190, 26, 26, 13, 149, + 16, 152, 54, 62, 104, 7, 46, 214, 75, 84, 5, 192, 0, 0, 0, + 128, 230, 82, 132, 63, 0, 0, 160, 252, 162, 33, 180, 64, 73, 6, + 130, 54, 217, 171, 242, 63, 81, 224, 163, 123, 238, 42, 66, 190, 206, + 43, 141, 67, 243, 157, 5, 192, 113, 179, 153, 187, 43, 92, 238, 63, + 254, 236, 31, 43, 224, 157, 244, 61, 0, 0, 0, 0, 232, 4, 26, + 191, 0, 0, 0, 0, 0, 0, 134, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 22, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = -9.925523772835732e-05; - test_msg.af1 = -2.5011104298755527e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = -3.166496753692627e-08; - test_msg.c_is = -2.0675361156463623e-07; - test_msg.c_rc = 305.21875; - test_msg.c_rs = 43.21875; - test_msg.c_uc = 2.1010637283325195e-06; - test_msg.c_us = 3.766268491744995e-06; - test_msg.dn = 5.26057626697412e-09; - test_msg.ecc = 0.009923744946718216; - test_msg.healthy = 1; - test_msg.inc = 0.9487513221807672; - test_msg.inc_dot = 3.000124967247105e-10; - test_msg.iode = 0; - test_msg.m0 = -2.666160271911327; - test_msg.omega0 = 1.1669551972594425; - test_msg.omegadot = -8.45999524990264e-09; - test_msg.prn = 22; - test_msg.sqrta = 5153.636667251587; - test_msg.tgd = -2.0023435354232788e-08; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = -2.7021241452652935; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -9.92552377284e-05 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -9.92552377284e-05, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -2.50111042988e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -2.50111042988e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - -3.16649675369e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected -3.16649675369e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - -2.06753611565e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected -2.06753611565e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 305.21875 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 305.21875, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - 43.21875 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected 43.21875, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - 2.10106372833e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected 2.10106372833e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 3.76626849174e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 3.76626849174e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 5.26057626697e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 5.26057626697e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00992374494672 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00992374494672, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.948751322181 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.948751322181, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - 3.00012496725e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected 3.00012496725e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - -2.66616027191 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected -2.66616027191, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - 1.16695519726 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected 1.16695519726, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -8.4599952499e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -8.4599952499e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 22) - << "incorrect value for last_msg_.prn, expected 22, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.63666725 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.63666725, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -2.00234353542e-08 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -2.00234353542e-08, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - -2.70212414527 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -2.70212414527, is " - << last_msg_.w; -} -class Test_auto_check_sbp_observation_msgEphemerisDepB5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgEphemerisDepB5 + : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgEphemerisDepB5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgEphemerisDepB5() { + assign(test_msg_.af0, 0.0003196117468178272); + assign(test_msg_.af1, -1.0231815394945443e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, 9.12696123123169e-08); + assign(test_msg_.c_is, 5.21540641784668e-08); + assign(test_msg_.c_rc, 247.28125); + assign(test_msg_.c_rs, -77.90625); + assign(test_msg_.c_uc, -3.723427653312683e-06); + assign(test_msg_.c_us, 7.178634405136108e-06); + assign(test_msg_.dn, 4.400897600764146e-09); + assign(test_msg_.ecc, 0.008178644930012524); + assign(test_msg_.healthy, 1); + assign(test_msg_.inc, 0.9755122017245301); + assign(test_msg_.inc_dot, -5.882387882209502e-10); + assign(test_msg_.iode, 0); + assign(test_msg_.m0, 1.9401823459824192); + assign(test_msg_.omega0, 2.241868028927766); + assign(test_msg_.omegadot, -7.962474526167494e-09); + assign(test_msg_.prn, 30); + assign(test_msg_.sqrta, 5153.7539920806885); + assign(test_msg_.tgd, -1.3504177331924438e-08); + assign(test_msg_.toc_tow, 410400.0); + assign(test_msg_.toc_wn, 1838); + assign(test_msg_.toe_tow, 410400.0); + assign(test_msg_.toe_wn, 1838); + assign(test_msg_.valid, 1); + assign(test_msg_.w, -0.5237901716088061); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_dep_b, + sizeof(msg->ephemeris_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisDepB); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x21aa; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 176; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_dep_b_t &lesser, + const sbp_msg_ephemeris_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisDepB, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB5, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ephemeris_dep_b_t test_msg_{}; + uint8_t encoded_frame_[176 + 8] = { 85, 70, 0, 195, 4, 176, 0, 0, 0, 0, 0, 0, 77, 190, 0, 0, 0, 0, 0, 122, 83, 192, 0, 0, 0, 0, 0, 233, 110, 64, 0, 0, 0, 0, 0, 60, 207, 190, 0, 0, 0, 0, 0, 28, 222, @@ -1070,128 +4188,474 @@ TEST_F(Test_auto_check_sbp_observation_msgEphemerisDepB5, Test) { 65, 46, 7, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 1, 1, 30, 0, 170, 33, }; + uint8_t encoded_payload_[176] = { + 0, 0, 0, 0, 0, 0, 77, 190, 0, 0, 0, 0, 0, 122, 83, + 192, 0, 0, 0, 0, 0, 233, 110, 64, 0, 0, 0, 0, 0, 60, + 207, 190, 0, 0, 0, 0, 0, 28, 222, 62, 0, 0, 0, 0, 0, + 128, 120, 62, 0, 0, 0, 0, 0, 0, 108, 62, 10, 230, 183, 140, + 214, 230, 50, 62, 54, 86, 196, 164, 252, 10, 255, 63, 0, 0, 0, + 36, 247, 191, 128, 63, 0, 0, 160, 5, 193, 33, 180, 64, 186, 138, + 81, 129, 88, 239, 1, 64, 94, 210, 120, 170, 106, 25, 65, 190, 103, + 213, 32, 155, 227, 194, 224, 191, 156, 47, 104, 93, 101, 55, 239, 63, + 196, 83, 100, 254, 51, 54, 4, 190, 0, 0, 0, 0, 50, 242, 52, + 63, 0, 0, 0, 0, 0, 0, 114, 189, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 128, 12, 25, 65, 46, 7, 0, 0, 0, + 0, 128, 12, 25, 65, 46, 7, 1, 1, 30, 0, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + + for (uint8_t i = 0; i < 176; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_dep_b_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_dep_b_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.healthy, greater.healthy); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.prn, greater.prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_tow, greater.toc_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toc_wn, greater.toc_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_tow, greater.toe_tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.toe_wn, greater.toe_wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.valid, greater.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_dep_b_t lesser = info.test_msg; + sbp_msg_ephemeris_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_DEP_B"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_dep_b, info.test_msg); - sbp_msg_ephemeris_dep_b_t test_msg{}; - test_msg.af0 = 0.0003196117468178272; - test_msg.af1 = -1.0231815394945443e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = 9.12696123123169e-08; - test_msg.c_is = 5.21540641784668e-08; - test_msg.c_rc = 247.28125; - test_msg.c_rs = -77.90625; - test_msg.c_uc = -3.723427653312683e-06; - test_msg.c_us = 7.178634405136108e-06; - test_msg.dn = 4.400897600764146e-09; - test_msg.ecc = 0.008178644930012524; - test_msg.healthy = 1; - test_msg.inc = 0.9755122017245301; - test_msg.inc_dot = -5.882387882209502e-10; - test_msg.iode = 0; - test_msg.m0 = 1.9401823459824192; - test_msg.omega0 = 2.241868028927766; - test_msg.omegadot = -7.962474526167494e-09; - test_msg.prn = 30; - test_msg.sqrta = 5153.7539920806885; - test_msg.tgd = -1.3504177331924438e-08; - test_msg.toc_tow = 410400.0; - test_msg.toc_wn = 1838; - test_msg.toe_tow = 410400.0; - test_msg.toe_wn = 1838; - test_msg.valid = 1; - test_msg.w = -0.5237901716088061; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - 0.000319611746818 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected 0.000319611746818, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -1.02318153949e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -1.02318153949e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - 9.12696123123e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected 9.12696123123e-08, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - 5.21540641785e-08 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected 5.21540641785e-08, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - 247.28125 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected 247.28125, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - -77.90625 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected -77.90625, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - -3.72342765331e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected -3.72342765331e-06, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 7.17863440514e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 7.17863440514e-06, is " - << last_msg_.c_us; - EXPECT_LT((last_msg_.dn * 100 - 4.40089760076e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 4.40089760076e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.00817864493001 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.00817864493001, is " - << last_msg_.ecc; - EXPECT_EQ(last_msg_.healthy, 1) - << "incorrect value for last_msg_.healthy, expected 1, is " - << last_msg_.healthy; - EXPECT_LT((last_msg_.inc * 100 - 0.975512201725 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.975512201725, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - -5.88238788221e-10 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected -5.88238788221e-10, " - "is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iode, 0) - << "incorrect value for last_msg_.iode, expected 0, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - 1.94018234598 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected 1.94018234598, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - 2.24186802893 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected 2.24186802893, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -7.96247452617e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -7.96247452617e-09, " - "is " - << last_msg_.omegadot; - EXPECT_EQ(last_msg_.prn, 30) - << "incorrect value for last_msg_.prn, expected 30, is " << last_msg_.prn; - EXPECT_LT((last_msg_.sqrta * 100 - 5153.75399208 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 5153.75399208, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -1.35041773319e-08 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -1.35041773319e-08, is " - << last_msg_.tgd; - EXPECT_LT((last_msg_.toc_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toc_tow, expected 410400.0, is " - << last_msg_.toc_tow; - EXPECT_EQ(last_msg_.toc_wn, 1838) - << "incorrect value for last_msg_.toc_wn, expected 1838, is " - << last_msg_.toc_wn; - EXPECT_LT((last_msg_.toe_tow * 100 - 410400.0 * 100), 0.05) - << "incorrect value for last_msg_.toe_tow, expected 410400.0, is " - << last_msg_.toe_tow; - EXPECT_EQ(last_msg_.toe_wn, 1838) - << "incorrect value for last_msg_.toe_wn, expected 1838, is " - << last_msg_.toe_wn; - EXPECT_EQ(last_msg_.valid, 1) - << "incorrect value for last_msg_.valid, expected 1, is " - << last_msg_.valid; - EXPECT_LT((last_msg_.w * 100 - -0.523790171609 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -0.523790171609, is " - << last_msg_.w; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_dep_b, info.test_msg); } + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[176]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 176); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 176), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 176); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisDepB5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_msgEphemerisQzss.cc b/c/test/cpp/auto_check_sbp_observation_msgEphemerisQzss.cc index bc667d9f2b..e821e48072 100644 --- a/c/test/cpp/auto_check_sbp_observation_msgEphemerisQzss.cc +++ b/c/test/cpp/auto_check_sbp_observation_msgEphemerisQzss.cc @@ -16,66 +16,308 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_msgEphemerisQzss0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_msgEphemerisQzss0 + : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgEphemerisQzss0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgEphemerisQzss0() { + assign(test_msg_.af0, -0.00036908406764268875); + assign(test_msg_.af1, -4.774847184307873e-12); + assign(test_msg_.af2, 0.0); + assign(test_msg_.c_ic, -1.1753290891647339e-06); + assign(test_msg_.c_is, 1.6205012798309326e-07); + assign(test_msg_.c_rc, -36.90625); + assign(test_msg_.c_rs, -457.8125); + assign(test_msg_.c_uc, -1.6197562217712402e-05); + assign(test_msg_.c_us, 8.247792720794678e-06); + assign(test_msg_.common.fit_interval, 14400); + assign(test_msg_.common.health_bits, 0); + assign(test_msg_.common.sid.code, 31); + assign(test_msg_.common.sid.sat, 193); + assign(test_msg_.common.toe.tow, 450000); + assign(test_msg_.common.toe.wn, 2154); + assign(test_msg_.common.ura, 2.0); + assign(test_msg_.common.valid, 0); + assign(test_msg_.dn, 2.678325848736433e-09); + assign(test_msg_.ecc, 0.07550019584596157); + assign(test_msg_.inc, 0.7309715119432375); + assign(test_msg_.inc_dot, 2.0000833114980698e-11); + assign(test_msg_.iodc, 817); + assign(test_msg_.iode, 49); + assign(test_msg_.m0, 0.30694242158961144); + assign(test_msg_.omega0, -1.1693743795366662); + assign(test_msg_.omegadot, -2.7936877968817684e-09); + assign(test_msg_.sqrta, 6493.172393798828); + assign(test_msg_.tgd, -5.587935447692871e-09); + assign(test_msg_.toc.tow, 450000); + assign(test_msg_.toc.wn, 2154); + assign(test_msg_.w, -1.5662079690885238); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_qzss_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ephemeris_qzss_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEphemerisQzss, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ephemeris_qzss_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEphemerisQzss); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ephemeris_qzss, + sizeof(msg->ephemeris_qzss)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ephemeris_qzss_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ephemeris_qzss, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEphemerisQzss); + info.sender_id = 61568; + info.preamble = 0x55; + info.crc = 0x177e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 139; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ephemeris_qzss_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ephemeris_qzss_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ephemeris_qzss_t &lesser, + const sbp_msg_ephemeris_qzss_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ephemeris_qzss_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ephemeris_qzss_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ephemeris_qzss_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ephemeris_qzss_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEphemerisQzss, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEphemerisQzss, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgEphemerisQzss, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgEphemerisQzss, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_observation_msgEphemerisQzss0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ephemeris_qzss_t test_msg_{}; + uint8_t encoded_frame_[139 + 8] = { 85, 142, 0, 128, 240, 139, 193, 31, 208, 221, 6, 0, 106, 8, 0, 0, 0, 64, 64, 56, 0, 0, 0, 0, 0, 0, 192, 177, 0, 232, 228, 195, 0, 160, 19, 194, 0, 224, 135, 183, 0, 96, 10, 55, 0, @@ -87,145 +329,497 @@ TEST_F(Test_auto_check_sbp_observation_msgEphemerisQzss0, Test) { 187, 253, 181, 61, 160, 129, 193, 185, 0, 0, 168, 172, 0, 0, 0, 0, 208, 221, 6, 0, 106, 8, 49, 49, 3, 126, 23, }; + uint8_t encoded_payload_[139] = { + 193, 31, 208, 221, 6, 0, 106, 8, 0, 0, 0, 64, 64, 56, + 0, 0, 0, 0, 0, 0, 192, 177, 0, 232, 228, 195, 0, 160, + 19, 194, 0, 224, 135, 183, 0, 96, 10, 55, 0, 192, 157, 181, + 0, 0, 46, 52, 167, 72, 107, 105, 179, 1, 39, 62, 15, 224, + 158, 211, 241, 164, 211, 63, 0, 0, 0, 24, 251, 83, 179, 63, + 0, 0, 0, 34, 44, 93, 185, 64, 143, 62, 206, 232, 193, 181, + 242, 191, 207, 216, 69, 106, 98, 255, 39, 190, 65, 132, 95, 22, + 48, 15, 249, 191, 249, 82, 67, 94, 30, 100, 231, 63, 117, 167, + 187, 233, 187, 253, 181, 61, 160, 129, 193, 185, 0, 0, 168, 172, + 0, 0, 0, 0, 208, 221, 6, 0, 106, 8, 49, 49, 3, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ephemeris_qzss_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEphemerisQzss, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ephemeris_qzss_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEphemerisQzss, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + + EXPECT_EQ(sbp_msg_ephemeris_qzss_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + + for (uint8_t i = 0; i < 139; i++) { + EXPECT_EQ( + sbp_msg_ephemeris_qzss_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_qzss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ephemeris_qzss_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEphemerisQzss, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_qzss_t msg{}; + + EXPECT_EQ(sbp_msg_ephemeris_qzss_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_qzss_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ephemeris_qzss_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_ephemeris_qzss_t test_msg{}; - test_msg.af0 = -0.00036908406764268875; - test_msg.af1 = -4.774847184307873e-12; - test_msg.af2 = 0.0; - test_msg.c_ic = -1.1753290891647339e-06; - test_msg.c_is = 1.6205012798309326e-07; - test_msg.c_rc = -36.90625; - test_msg.c_rs = -457.8125; - test_msg.c_uc = -1.6197562217712402e-05; - test_msg.c_us = 8.247792720794678e-06; - test_msg.common.fit_interval = 14400; - test_msg.common.health_bits = 0; - test_msg.common.sid.code = 31; - test_msg.common.sid.sat = 193; - test_msg.common.toe.tow = 450000; - test_msg.common.toe.wn = 2154; - test_msg.common.ura = 2.0; - test_msg.common.valid = 0; - test_msg.dn = 2.678325848736433e-09; - test_msg.ecc = 0.07550019584596157; - test_msg.inc = 0.7309715119432375; - test_msg.inc_dot = 2.0000833114980698e-11; - test_msg.iodc = 817; - test_msg.iode = 49; - test_msg.m0 = 0.30694242158961144; - test_msg.omega0 = -1.1693743795366662; - test_msg.omegadot = -2.7936877968817684e-09; - test_msg.sqrta = 6493.172393798828; - test_msg.tgd = -5.587935447692871e-09; - test_msg.toc.tow = 450000; - test_msg.toc.wn = 2154; - test_msg.w = -1.5662079690885238; - - EXPECT_EQ(send_message(61568, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61568); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_LT((last_msg_.af0 * 100 - -0.000369084067643 * 100), 0.05) - << "incorrect value for last_msg_.af0, expected -0.000369084067643, is " - << last_msg_.af0; - EXPECT_LT((last_msg_.af1 * 100 - -4.77484718431e-12 * 100), 0.05) - << "incorrect value for last_msg_.af1, expected -4.77484718431e-12, is " - << last_msg_.af1; - EXPECT_LT((last_msg_.af2 * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.af2, expected 0.0, is " - << last_msg_.af2; - EXPECT_LT((last_msg_.c_ic * 100 - -1.17532908916e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_ic, expected -1.17532908916e-06, is " - << last_msg_.c_ic; - EXPECT_LT((last_msg_.c_is * 100 - 1.62050127983e-07 * 100), 0.05) - << "incorrect value for last_msg_.c_is, expected 1.62050127983e-07, is " - << last_msg_.c_is; - EXPECT_LT((last_msg_.c_rc * 100 - -36.90625 * 100), 0.05) - << "incorrect value for last_msg_.c_rc, expected -36.90625, is " - << last_msg_.c_rc; - EXPECT_LT((last_msg_.c_rs * 100 - -457.8125 * 100), 0.05) - << "incorrect value for last_msg_.c_rs, expected -457.8125, is " - << last_msg_.c_rs; - EXPECT_LT((last_msg_.c_uc * 100 - -1.61975622177e-05 * 100), 0.05) - << "incorrect value for last_msg_.c_uc, expected -1.61975622177e-05, is " - << last_msg_.c_uc; - EXPECT_LT((last_msg_.c_us * 100 - 8.24779272079e-06 * 100), 0.05) - << "incorrect value for last_msg_.c_us, expected 8.24779272079e-06, is " - << last_msg_.c_us; - EXPECT_EQ(last_msg_.common.fit_interval, 14400) - << "incorrect value for last_msg_.common.fit_interval, expected 14400, " - "is " - << last_msg_.common.fit_interval; - EXPECT_EQ(last_msg_.common.health_bits, 0) - << "incorrect value for last_msg_.common.health_bits, expected 0, is " - << last_msg_.common.health_bits; - EXPECT_EQ(last_msg_.common.sid.code, 31) - << "incorrect value for last_msg_.common.sid.code, expected 31, is " - << last_msg_.common.sid.code; - EXPECT_EQ(last_msg_.common.sid.sat, 193) - << "incorrect value for last_msg_.common.sid.sat, expected 193, is " - << last_msg_.common.sid.sat; - EXPECT_EQ(last_msg_.common.toe.tow, 450000) - << "incorrect value for last_msg_.common.toe.tow, expected 450000, is " - << last_msg_.common.toe.tow; - EXPECT_EQ(last_msg_.common.toe.wn, 2154) - << "incorrect value for last_msg_.common.toe.wn, expected 2154, is " - << last_msg_.common.toe.wn; - EXPECT_LT((last_msg_.common.ura * 100 - 2.0 * 100), 0.05) - << "incorrect value for last_msg_.common.ura, expected 2.0, is " - << last_msg_.common.ura; - EXPECT_EQ(last_msg_.common.valid, 0) - << "incorrect value for last_msg_.common.valid, expected 0, is " - << last_msg_.common.valid; - EXPECT_LT((last_msg_.dn * 100 - 2.67832584874e-09 * 100), 0.05) - << "incorrect value for last_msg_.dn, expected 2.67832584874e-09, is " - << last_msg_.dn; - EXPECT_LT((last_msg_.ecc * 100 - 0.075500195846 * 100), 0.05) - << "incorrect value for last_msg_.ecc, expected 0.075500195846, is " - << last_msg_.ecc; - EXPECT_LT((last_msg_.inc * 100 - 0.730971511943 * 100), 0.05) - << "incorrect value for last_msg_.inc, expected 0.730971511943, is " - << last_msg_.inc; - EXPECT_LT((last_msg_.inc_dot * 100 - 2.0000833115e-11 * 100), 0.05) - << "incorrect value for last_msg_.inc_dot, expected 2.0000833115e-11, is " - << last_msg_.inc_dot; - EXPECT_EQ(last_msg_.iodc, 817) - << "incorrect value for last_msg_.iodc, expected 817, is " - << last_msg_.iodc; - EXPECT_EQ(last_msg_.iode, 49) - << "incorrect value for last_msg_.iode, expected 49, is " - << last_msg_.iode; - EXPECT_LT((last_msg_.m0 * 100 - 0.30694242159 * 100), 0.05) - << "incorrect value for last_msg_.m0, expected 0.30694242159, is " - << last_msg_.m0; - EXPECT_LT((last_msg_.omega0 * 100 - -1.16937437954 * 100), 0.05) - << "incorrect value for last_msg_.omega0, expected -1.16937437954, is " - << last_msg_.omega0; - EXPECT_LT((last_msg_.omegadot * 100 - -2.79368779688e-09 * 100), 0.05) - << "incorrect value for last_msg_.omegadot, expected -2.79368779688e-09, " - "is " - << last_msg_.omegadot; - EXPECT_LT((last_msg_.sqrta * 100 - 6493.1723938 * 100), 0.05) - << "incorrect value for last_msg_.sqrta, expected 6493.1723938, is " - << last_msg_.sqrta; - EXPECT_LT((last_msg_.tgd * 100 - -5.58793544769e-09 * 100), 0.05) - << "incorrect value for last_msg_.tgd, expected -5.58793544769e-09, is " - << last_msg_.tgd; - EXPECT_EQ(last_msg_.toc.tow, 450000) - << "incorrect value for last_msg_.toc.tow, expected 450000, is " - << last_msg_.toc.tow; - EXPECT_EQ(last_msg_.toc.wn, 2154) - << "incorrect value for last_msg_.toc.wn, expected 2154, is " - << last_msg_.toc.wn; - EXPECT_LT((last_msg_.w * 100 - -1.56620796909 * 100), 0.05) - << "incorrect value for last_msg_.w, expected -1.56620796909, is " - << last_msg_.w; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ephemeris_qzss_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEphemerisQzss, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.af0, greater.af0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.af1, greater.af1); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.af2, greater.af2); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_ic, greater.c_ic); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_is, greater.c_is); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_rc, greater.c_rc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_rs, greater.c_rs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_uc, greater.c_uc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.c_us, greater.c_us); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.fit_interval, + greater.common.fit_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.health_bits, greater.common.health_bits); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.code, greater.common.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.sid.sat, greater.common.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.tow, greater.common.toe.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.toe.wn, greater.common.toe.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.ura, greater.common.ura); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.common.valid, greater.common.valid); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.dn, greater.dn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.ecc, greater.ecc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.inc, greater.inc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.inc_dot, greater.inc_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.iodc, greater.iodc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.iode, greater.iode); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.m0, greater.m0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.omega0, greater.omega0); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.omegadot, greater.omegadot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.sqrta, greater.sqrta); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.tgd, greater.tgd); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.toc.tow, greater.toc.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.toc.wn, greater.toc.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ephemeris_qzss_t lesser = info.test_msg; + sbp_msg_ephemeris_qzss_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEphemerisQzss); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_EPHEMERIS_QZSS"); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ephemeris_qzss_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ephemeris_qzss_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ephemeris_qzss, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ephemeris_qzss, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[139]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 139); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 139), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ephemeris_qzss_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 139); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEphemerisQzss, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgEphemerisQzss0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEphemerisQzss, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_observation_msgObsDepA.cc b/c/test/cpp/auto_check_sbp_observation_msgObsDepA.cc index bd1f0edeed..5f774d5c60 100644 --- a/c/test/cpp/auto_check_sbp_observation_msgObsDepA.cc +++ b/c/test/cpp/auto_check_sbp_observation_msgObsDepA.cc @@ -16,66 +16,322 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_observation_msgObsDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_observation_msgObsDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgObsDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgObsDepA0() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 407084600); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 7); + + assign(test_msg_.obs[0].L.f, 33); + assign(test_msg_.obs[0].L.i, -36108); + assign(test_msg_.obs[0].P, 2046421816); + assign(test_msg_.obs[0].cn0, 46); + assign(test_msg_.obs[0].lock, 55875); + assign(test_msg_.obs[0].prn, 0); + + assign(test_msg_.obs[1].L.f, 98); + assign(test_msg_.obs[1].L.i, 203030); + assign(test_msg_.obs[1].P, 2085014510); + assign(test_msg_.obs[1].cn0, 43); + assign(test_msg_.obs[1].lock, 40376); + assign(test_msg_.obs[1].prn, 2); + + assign(test_msg_.obs[2].L.f, 185); + assign(test_msg_.obs[2].L.i, -178306); + assign(test_msg_.obs[2].P, 2110096816); + assign(test_msg_.obs[2].cn0, 39); + assign(test_msg_.obs[2].lock, 14148); + assign(test_msg_.obs[2].prn, 3); + + assign(test_msg_.obs[3].L.f, 139); + assign(test_msg_.obs[3].L.i, -137374); + assign(test_msg_.obs[3].P, 2208476476); + assign(test_msg_.obs[3].cn0, 30); + assign(test_msg_.obs[3].lock, 4129); + assign(test_msg_.obs[3].prn, 10); + + assign(test_msg_.obs[4].L.f, 40); + assign(test_msg_.obs[4].L.i, -167638); + assign(test_msg_.obs[4].P, 2298000000); + assign(test_msg_.obs[4].cn0, 20); + assign(test_msg_.obs[4].lock, 18218); + assign(test_msg_.obs[4].prn, 13); + + assign(test_msg_.obs[5].L.f, 64); + assign(test_msg_.obs[5].L.i, 209919); + assign(test_msg_.obs[5].P, 2266101494); + assign(test_msg_.obs[5].cn0, 27); + assign(test_msg_.obs[5].lock, 63852); + assign(test_msg_.obs[5].prn, 22); + + assign(test_msg_.obs[6].L.f, 31); + assign(test_msg_.obs[6].L.i, -53117); + assign(test_msg_.obs[6].P, 1987193298); + assign(test_msg_.obs[6].cn0, 52); + assign(test_msg_.obs[6].lock, 15074); + assign(test_msg_.obs[6].prn, 30); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xd917; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 98; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); -TEST_F(Test_auto_check_sbp_observation_msgObsDepA0, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[98 + 8] = { 85, 69, 0, 195, 4, 98, 56, 158, 67, 24, 46, 7, 32, 56, 235, 249, 121, 244, 114, 255, 255, 33, 46, 67, 218, 0, 238, 203, 70, 124, 22, 25, 3, 0, 98, 43, 184, 157, 2, 176, 133, 197, @@ -85,1159 +341,4361 @@ TEST_F(Test_auto_check_sbp_observation_msgObsDepA0, Test) { 3, 0, 64, 27, 108, 249, 22, 210, 41, 114, 118, 131, 48, 255, 255, 31, 52, 226, 58, 30, 23, 217, }; + uint8_t encoded_payload_[98] = { + 56, 158, 67, 24, 46, 7, 32, 56, 235, 249, 121, 244, 114, 255, + 255, 33, 46, 67, 218, 0, 238, 203, 70, 124, 22, 25, 3, 0, + 98, 43, 184, 157, 2, 176, 133, 197, 125, 126, 71, 253, 255, 185, + 39, 68, 55, 3, 60, 173, 162, 131, 98, 231, 253, 255, 139, 30, + 33, 16, 10, 128, 178, 248, 136, 42, 113, 253, 255, 40, 20, 42, + 71, 13, 246, 246, 17, 135, 255, 51, 3, 0, 64, 27, 108, 249, + 22, 210, 41, 114, 118, 131, 48, 255, 255, 31, 52, 226, 58, 30, + }; +}; - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 407084600; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 7; - - test_msg.obs[0].L.f = 33; - test_msg.obs[0].L.i = -36108; - test_msg.obs[0].P = 2046421816; - test_msg.obs[0].cn0 = 46; - test_msg.obs[0].lock = 55875; - test_msg.obs[0].prn = 0; - - test_msg.obs[1].L.f = 98; - test_msg.obs[1].L.i = 203030; - test_msg.obs[1].P = 2085014510; - test_msg.obs[1].cn0 = 43; - test_msg.obs[1].lock = 40376; - test_msg.obs[1].prn = 2; - - test_msg.obs[2].L.f = 185; - test_msg.obs[2].L.i = -178306; - test_msg.obs[2].P = 2110096816; - test_msg.obs[2].cn0 = 39; - test_msg.obs[2].lock = 14148; - test_msg.obs[2].prn = 3; - - test_msg.obs[3].L.f = 139; - test_msg.obs[3].L.i = -137374; - test_msg.obs[3].P = 2208476476; - test_msg.obs[3].cn0 = 30; - test_msg.obs[3].lock = 4129; - test_msg.obs[3].prn = 10; - - test_msg.obs[4].L.f = 40; - test_msg.obs[4].L.i = -167638; - test_msg.obs[4].P = 2298000000; - test_msg.obs[4].cn0 = 20; - test_msg.obs[4].lock = 18218; - test_msg.obs[4].prn = 13; - - test_msg.obs[5].L.f = 64; - test_msg.obs[5].L.i = 209919; - test_msg.obs[5].P = 2266101494; - test_msg.obs[5].cn0 = 27; - test_msg.obs[5].lock = 63852; - test_msg.obs[5].prn = 22; - - test_msg.obs[6].L.f = 31; - test_msg.obs[6].L.i = -53117; - test_msg.obs[6].P = 1987193298; - test_msg.obs[6].cn0 = 52; - test_msg.obs[6].lock = 15074; - test_msg.obs[6].prn = 30; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407084600) - << "incorrect value for last_msg_.header.t.tow, expected 407084600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 7) - << "incorrect value for last_msg_.n_obs, expected 7, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 33) - << "incorrect value for last_msg_.obs[0].L.f, expected 33, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -36108) - << "incorrect value for last_msg_.obs[0].L.i, expected -36108, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2046421816) - << "incorrect value for last_msg_.obs[0].P, expected 2046421816, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 46) - << "incorrect value for last_msg_.obs[0].cn0, expected 46, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 55875) - << "incorrect value for last_msg_.obs[0].lock, expected 55875, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 0) - << "incorrect value for last_msg_.obs[0].prn, expected 0, is " - << last_msg_.obs[0].prn; - EXPECT_EQ(last_msg_.obs[1].L.f, 98) - << "incorrect value for last_msg_.obs[1].L.f, expected 98, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 203030) - << "incorrect value for last_msg_.obs[1].L.i, expected 203030, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2085014510) - << "incorrect value for last_msg_.obs[1].P, expected 2085014510, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 43) - << "incorrect value for last_msg_.obs[1].cn0, expected 43, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 40376) - << "incorrect value for last_msg_.obs[1].lock, expected 40376, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].prn, 2) - << "incorrect value for last_msg_.obs[1].prn, expected 2, is " - << last_msg_.obs[1].prn; - EXPECT_EQ(last_msg_.obs[2].L.f, 185) - << "incorrect value for last_msg_.obs[2].L.f, expected 185, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -178306) - << "incorrect value for last_msg_.obs[2].L.i, expected -178306, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2110096816) - << "incorrect value for last_msg_.obs[2].P, expected 2110096816, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 39) - << "incorrect value for last_msg_.obs[2].cn0, expected 39, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 14148) - << "incorrect value for last_msg_.obs[2].lock, expected 14148, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].prn, 3) - << "incorrect value for last_msg_.obs[2].prn, expected 3, is " - << last_msg_.obs[2].prn; - EXPECT_EQ(last_msg_.obs[3].L.f, 139) - << "incorrect value for last_msg_.obs[3].L.f, expected 139, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, -137374) - << "incorrect value for last_msg_.obs[3].L.i, expected -137374, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2208476476) - << "incorrect value for last_msg_.obs[3].P, expected 2208476476, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 30) - << "incorrect value for last_msg_.obs[3].cn0, expected 30, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 4129) - << "incorrect value for last_msg_.obs[3].lock, expected 4129, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].prn, 10) - << "incorrect value for last_msg_.obs[3].prn, expected 10, is " - << last_msg_.obs[3].prn; - EXPECT_EQ(last_msg_.obs[4].L.f, 40) - << "incorrect value for last_msg_.obs[4].L.f, expected 40, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, -167638) - << "incorrect value for last_msg_.obs[4].L.i, expected -167638, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 2298000000) - << "incorrect value for last_msg_.obs[4].P, expected 2298000000, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 20) - << "incorrect value for last_msg_.obs[4].cn0, expected 20, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 18218) - << "incorrect value for last_msg_.obs[4].lock, expected 18218, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].prn, 13) - << "incorrect value for last_msg_.obs[4].prn, expected 13, is " - << last_msg_.obs[4].prn; - EXPECT_EQ(last_msg_.obs[5].L.f, 64) - << "incorrect value for last_msg_.obs[5].L.f, expected 64, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 209919) - << "incorrect value for last_msg_.obs[5].L.i, expected 209919, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 2266101494) - << "incorrect value for last_msg_.obs[5].P, expected 2266101494, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 27) - << "incorrect value for last_msg_.obs[5].cn0, expected 27, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].lock, 63852) - << "incorrect value for last_msg_.obs[5].lock, expected 63852, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].prn, 22) - << "incorrect value for last_msg_.obs[5].prn, expected 22, is " - << last_msg_.obs[5].prn; - EXPECT_EQ(last_msg_.obs[6].L.f, 31) - << "incorrect value for last_msg_.obs[6].L.f, expected 31, is " - << last_msg_.obs[6].L.f; - EXPECT_EQ(last_msg_.obs[6].L.i, -53117) - << "incorrect value for last_msg_.obs[6].L.i, expected -53117, is " - << last_msg_.obs[6].L.i; - EXPECT_EQ(last_msg_.obs[6].P, 1987193298) - << "incorrect value for last_msg_.obs[6].P, expected 1987193298, is " - << last_msg_.obs[6].P; - EXPECT_EQ(last_msg_.obs[6].cn0, 52) - << "incorrect value for last_msg_.obs[6].cn0, expected 52, is " - << last_msg_.obs[6].cn0; - EXPECT_EQ(last_msg_.obs[6].lock, 15074) - << "incorrect value for last_msg_.obs[6].lock, expected 15074, is " - << last_msg_.obs[6].lock; - EXPECT_EQ(last_msg_.obs[6].prn, 30) - << "incorrect value for last_msg_.obs[6].prn, expected 30, is " - << last_msg_.obs[6].prn; -} -class Test_auto_check_sbp_observation_msgObsDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgObsDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + + for (uint8_t i = 0; i < 98; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_observation_msgObsDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 69, 0, 195, 4, 20, 56, 158, 67, 24, 46, 7, 33, 84, - 52, 164, 117, 102, 32, 0, 0, 147, 62, 62, 250, 31, 234, 14, - }; + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 407084600; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 1; - - test_msg.obs[0].L.f = 147; - test_msg.obs[0].L.i = 8294; - test_msg.obs[0].P = 1973695572; - test_msg.obs[0].cn0 = 62; - test_msg.obs[0].lock = 64062; - test_msg.obs[0].prn = 31; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407084600) - << "incorrect value for last_msg_.header.t.tow, expected 407084600, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 1) - << "incorrect value for last_msg_.n_obs, expected 1, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 147) - << "incorrect value for last_msg_.obs[0].L.f, expected 147, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 8294) - << "incorrect value for last_msg_.obs[0].L.i, expected 8294, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1973695572) - << "incorrect value for last_msg_.obs[0].P, expected 1973695572, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 62) - << "incorrect value for last_msg_.obs[0].cn0, expected 62, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 64062) - << "incorrect value for last_msg_.obs[0].lock, expected 64062, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 31) - << "incorrect value for last_msg_.obs[0].prn, expected 31, is " - << last_msg_.obs[0].prn; -} -class Test_auto_check_sbp_observation_msgObsDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgObsDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_observation_msgObsDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 69, 0, 195, 4, 98, 0, 159, 67, 24, 46, 7, 32, 32, - 209, 249, 121, 145, 114, 255, 255, 141, 45, 67, 218, 0, 177, 128, - 70, 124, 79, 27, 3, 0, 159, 44, 184, 157, 2, 59, 135, 197, - 125, 175, 69, 253, 255, 77, 40, 68, 55, 3, 211, 172, 162, 131, - 177, 229, 253, 255, 20, 31, 33, 16, 10, 128, 178, 248, 136, 116, - 111, 253, 255, 94, 21, 42, 71, 13, 182, 173, 17, 135, 37, 54, - 3, 0, 214, 27, 108, 249, 22, 91, 20, 114, 118, 240, 47, 255, - 255, 129, 52, 226, 58, 30, 200, 119, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 32; - test_msg.header.t.tow = 407084800; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 7; - - test_msg.obs[0].L.f = 141; - test_msg.obs[0].L.i = -36207; - test_msg.obs[0].P = 2046415136; - test_msg.obs[0].cn0 = 45; - test_msg.obs[0].lock = 55875; - test_msg.obs[0].prn = 0; - - test_msg.obs[1].L.f = 159; - test_msg.obs[1].L.i = 203599; - test_msg.obs[1].P = 2084995249; - test_msg.obs[1].cn0 = 44; - test_msg.obs[1].lock = 40376; - test_msg.obs[1].prn = 2; - - test_msg.obs[2].L.f = 77; - test_msg.obs[2].L.i = -178769; - test_msg.obs[2].P = 2110097211; - test_msg.obs[2].cn0 = 40; - test_msg.obs[2].lock = 14148; - test_msg.obs[2].prn = 3; - - test_msg.obs[3].L.f = 20; - test_msg.obs[3].L.i = -137807; - test_msg.obs[3].P = 2208476371; - test_msg.obs[3].cn0 = 31; - test_msg.obs[3].lock = 4129; - test_msg.obs[3].prn = 10; - - test_msg.obs[4].L.f = 94; - test_msg.obs[4].L.i = -168076; - test_msg.obs[4].P = 2298000000; - test_msg.obs[4].cn0 = 21; - test_msg.obs[4].lock = 18218; - test_msg.obs[4].prn = 13; - - test_msg.obs[5].L.f = 214; - test_msg.obs[5].L.i = 210469; - test_msg.obs[5].P = 2266082742; - test_msg.obs[5].cn0 = 27; - test_msg.obs[5].lock = 63852; - test_msg.obs[5].prn = 22; - - test_msg.obs[6].L.f = 129; - test_msg.obs[6].L.i = -53264; - test_msg.obs[6].P = 1987187803; - test_msg.obs[6].cn0 = 52; - test_msg.obs[6].lock = 15074; - test_msg.obs[6].prn = 30; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 32) - << "incorrect value for last_msg_.header.n_obs, expected 32, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407084800) - << "incorrect value for last_msg_.header.t.tow, expected 407084800, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 7) - << "incorrect value for last_msg_.n_obs, expected 7, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 141) - << "incorrect value for last_msg_.obs[0].L.f, expected 141, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -36207) - << "incorrect value for last_msg_.obs[0].L.i, expected -36207, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2046415136) - << "incorrect value for last_msg_.obs[0].P, expected 2046415136, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 45) - << "incorrect value for last_msg_.obs[0].cn0, expected 45, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 55875) - << "incorrect value for last_msg_.obs[0].lock, expected 55875, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 0) - << "incorrect value for last_msg_.obs[0].prn, expected 0, is " - << last_msg_.obs[0].prn; - EXPECT_EQ(last_msg_.obs[1].L.f, 159) - << "incorrect value for last_msg_.obs[1].L.f, expected 159, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, 203599) - << "incorrect value for last_msg_.obs[1].L.i, expected 203599, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2084995249) - << "incorrect value for last_msg_.obs[1].P, expected 2084995249, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 44) - << "incorrect value for last_msg_.obs[1].cn0, expected 44, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 40376) - << "incorrect value for last_msg_.obs[1].lock, expected 40376, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].prn, 2) - << "incorrect value for last_msg_.obs[1].prn, expected 2, is " - << last_msg_.obs[1].prn; - EXPECT_EQ(last_msg_.obs[2].L.f, 77) - << "incorrect value for last_msg_.obs[2].L.f, expected 77, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -178769) - << "incorrect value for last_msg_.obs[2].L.i, expected -178769, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2110097211) - << "incorrect value for last_msg_.obs[2].P, expected 2110097211, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 40) - << "incorrect value for last_msg_.obs[2].cn0, expected 40, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 14148) - << "incorrect value for last_msg_.obs[2].lock, expected 14148, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].prn, 3) - << "incorrect value for last_msg_.obs[2].prn, expected 3, is " - << last_msg_.obs[2].prn; - EXPECT_EQ(last_msg_.obs[3].L.f, 20) - << "incorrect value for last_msg_.obs[3].L.f, expected 20, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, -137807) - << "incorrect value for last_msg_.obs[3].L.i, expected -137807, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2208476371) - << "incorrect value for last_msg_.obs[3].P, expected 2208476371, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 31) - << "incorrect value for last_msg_.obs[3].cn0, expected 31, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 4129) - << "incorrect value for last_msg_.obs[3].lock, expected 4129, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].prn, 10) - << "incorrect value for last_msg_.obs[3].prn, expected 10, is " - << last_msg_.obs[3].prn; - EXPECT_EQ(last_msg_.obs[4].L.f, 94) - << "incorrect value for last_msg_.obs[4].L.f, expected 94, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, -168076) - << "incorrect value for last_msg_.obs[4].L.i, expected -168076, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 2298000000) - << "incorrect value for last_msg_.obs[4].P, expected 2298000000, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 21) - << "incorrect value for last_msg_.obs[4].cn0, expected 21, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 18218) - << "incorrect value for last_msg_.obs[4].lock, expected 18218, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].prn, 13) - << "incorrect value for last_msg_.obs[4].prn, expected 13, is " - << last_msg_.obs[4].prn; - EXPECT_EQ(last_msg_.obs[5].L.f, 214) - << "incorrect value for last_msg_.obs[5].L.f, expected 214, is " - << last_msg_.obs[5].L.f; - EXPECT_EQ(last_msg_.obs[5].L.i, 210469) - << "incorrect value for last_msg_.obs[5].L.i, expected 210469, is " - << last_msg_.obs[5].L.i; - EXPECT_EQ(last_msg_.obs[5].P, 2266082742) - << "incorrect value for last_msg_.obs[5].P, expected 2266082742, is " - << last_msg_.obs[5].P; - EXPECT_EQ(last_msg_.obs[5].cn0, 27) - << "incorrect value for last_msg_.obs[5].cn0, expected 27, is " - << last_msg_.obs[5].cn0; - EXPECT_EQ(last_msg_.obs[5].lock, 63852) - << "incorrect value for last_msg_.obs[5].lock, expected 63852, is " - << last_msg_.obs[5].lock; - EXPECT_EQ(last_msg_.obs[5].prn, 22) - << "incorrect value for last_msg_.obs[5].prn, expected 22, is " - << last_msg_.obs[5].prn; - EXPECT_EQ(last_msg_.obs[6].L.f, 129) - << "incorrect value for last_msg_.obs[6].L.f, expected 129, is " - << last_msg_.obs[6].L.f; - EXPECT_EQ(last_msg_.obs[6].L.i, -53264) - << "incorrect value for last_msg_.obs[6].L.i, expected -53264, is " - << last_msg_.obs[6].L.i; - EXPECT_EQ(last_msg_.obs[6].P, 1987187803) - << "incorrect value for last_msg_.obs[6].P, expected 1987187803, is " - << last_msg_.obs[6].P; - EXPECT_EQ(last_msg_.obs[6].cn0, 52) - << "incorrect value for last_msg_.obs[6].cn0, expected 52, is " - << last_msg_.obs[6].cn0; - EXPECT_EQ(last_msg_.obs[6].lock, 15074) - << "incorrect value for last_msg_.obs[6].lock, expected 15074, is " - << last_msg_.obs[6].lock; - EXPECT_EQ(last_msg_.obs[6].prn, 30) - << "incorrect value for last_msg_.obs[6].prn, expected 30, is " - << last_msg_.obs[6].prn; -} -class Test_auto_check_sbp_observation_msgObsDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgObsDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_observation_msgObsDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 69, 0, 195, 4, 20, 0, 159, 67, 24, 46, 7, 33, 49, - 19, 164, 117, 120, 32, 0, 0, 222, 63, 62, 250, 31, 11, 231, - }; +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 33; - test_msg.header.t.tow = 407084800; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 1; - - test_msg.obs[0].L.f = 222; - test_msg.obs[0].L.i = 8312; - test_msg.obs[0].P = 1973687089; - test_msg.obs[0].cn0 = 63; - test_msg.obs[0].lock = 64062; - test_msg.obs[0].prn = 31; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 33) - << "incorrect value for last_msg_.header.n_obs, expected 33, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407084800) - << "incorrect value for last_msg_.header.t.tow, expected 407084800, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 1) - << "incorrect value for last_msg_.n_obs, expected 1, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 222) - << "incorrect value for last_msg_.obs[0].L.f, expected 222, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, 8312) - << "incorrect value for last_msg_.obs[0].L.i, expected 8312, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 1973687089) - << "incorrect value for last_msg_.obs[0].P, expected 1973687089, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 63) - << "incorrect value for last_msg_.obs[0].cn0, expected 63, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 64062) - << "incorrect value for last_msg_.obs[0].lock, expected 64062, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 31) - << "incorrect value for last_msg_.obs[0].prn, expected 31, is " - << last_msg_.obs[0].prn; -} -class Test_auto_check_sbp_observation_msgObsDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_observation_msgObsDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } -TEST_F(Test_auto_check_sbp_observation_msgObsDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 69, 0, 195, 4, 72, 96, 162, 68, 24, 46, 7, 16, 87, - 132, 217, 121, 121, 148, 255, 255, 189, 43, 175, 147, 0, 132, 64, - 200, 125, 106, 31, 254, 255, 1, 41, 14, 177, 3, 128, 178, 248, - 136, 70, 68, 254, 255, 166, 18, 184, 133, 13, 24, 127, 178, 134, - 6, 25, 2, 0, 249, 28, 33, 96, 22, 170, 104, 86, 118, 67, - 112, 255, 255, 203, 56, 208, 88, 30, 43, 107, - }; + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].prn, greater.obs[1].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].prn, greater.obs[2].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].prn, greater.obs[3].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].prn, greater.obs[4].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].prn, greater.obs[5].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.f, greater.obs[6].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.i, greater.obs[6].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].P, greater.obs[6].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].cn0, greater.obs[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].lock, greater.obs[6].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].prn, greater.obs[6].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 16; - test_msg.header.t.tow = 407151200; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 5; - - test_msg.obs[0].L.f = 189; - test_msg.obs[0].L.i = -27527; - test_msg.obs[0].P = 2044298327; - test_msg.obs[0].cn0 = 43; - test_msg.obs[0].lock = 37807; - test_msg.obs[0].prn = 0; - - test_msg.obs[1].L.f = 1; - test_msg.obs[1].L.i = -123030; - test_msg.obs[1].P = 2110275716; - test_msg.obs[1].cn0 = 41; - test_msg.obs[1].lock = 45326; - test_msg.obs[1].prn = 3; - - test_msg.obs[2].L.f = 166; - test_msg.obs[2].L.i = -113594; - test_msg.obs[2].P = 2298000000; - test_msg.obs[2].cn0 = 18; - test_msg.obs[2].lock = 34232; - test_msg.obs[2].prn = 13; - - test_msg.obs[3].L.f = 249; - test_msg.obs[3].L.i = 137478; - test_msg.obs[3].P = 2259844888; - test_msg.obs[3].cn0 = 28; - test_msg.obs[3].lock = 24609; - test_msg.obs[3].prn = 22; - - test_msg.obs[4].L.f = 203; - test_msg.obs[4].L.i = -36797; - test_msg.obs[4].P = 1985374378; - test_msg.obs[4].cn0 = 56; - test_msg.obs[4].lock = 22736; - test_msg.obs[4].prn = 30; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 16) - << "incorrect value for last_msg_.header.n_obs, expected 16, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407151200) - << "incorrect value for last_msg_.header.t.tow, expected 407151200, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 5) - << "incorrect value for last_msg_.n_obs, expected 5, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 189) - << "incorrect value for last_msg_.obs[0].L.f, expected 189, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -27527) - << "incorrect value for last_msg_.obs[0].L.i, expected -27527, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2044298327) - << "incorrect value for last_msg_.obs[0].P, expected 2044298327, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 43) - << "incorrect value for last_msg_.obs[0].cn0, expected 43, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 37807) - << "incorrect value for last_msg_.obs[0].lock, expected 37807, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 0) - << "incorrect value for last_msg_.obs[0].prn, expected 0, is " - << last_msg_.obs[0].prn; - EXPECT_EQ(last_msg_.obs[1].L.f, 1) - << "incorrect value for last_msg_.obs[1].L.f, expected 1, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, -123030) - << "incorrect value for last_msg_.obs[1].L.i, expected -123030, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2110275716) - << "incorrect value for last_msg_.obs[1].P, expected 2110275716, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 41) - << "incorrect value for last_msg_.obs[1].cn0, expected 41, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 45326) - << "incorrect value for last_msg_.obs[1].lock, expected 45326, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].prn, 3) - << "incorrect value for last_msg_.obs[1].prn, expected 3, is " - << last_msg_.obs[1].prn; - EXPECT_EQ(last_msg_.obs[2].L.f, 166) - << "incorrect value for last_msg_.obs[2].L.f, expected 166, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -113594) - << "incorrect value for last_msg_.obs[2].L.i, expected -113594, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2298000000) - << "incorrect value for last_msg_.obs[2].P, expected 2298000000, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 18) - << "incorrect value for last_msg_.obs[2].cn0, expected 18, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 34232) - << "incorrect value for last_msg_.obs[2].lock, expected 34232, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].prn, 13) - << "incorrect value for last_msg_.obs[2].prn, expected 13, is " - << last_msg_.obs[2].prn; - EXPECT_EQ(last_msg_.obs[3].L.f, 249) - << "incorrect value for last_msg_.obs[3].L.f, expected 249, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 137478) - << "incorrect value for last_msg_.obs[3].L.i, expected 137478, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2259844888) - << "incorrect value for last_msg_.obs[3].P, expected 2259844888, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 28) - << "incorrect value for last_msg_.obs[3].cn0, expected 28, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 24609) - << "incorrect value for last_msg_.obs[3].lock, expected 24609, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].prn, 22) - << "incorrect value for last_msg_.obs[3].prn, expected 22, is " - << last_msg_.obs[3].prn; - EXPECT_EQ(last_msg_.obs[4].L.f, 203) - << "incorrect value for last_msg_.obs[4].L.f, expected 203, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, -36797) - << "incorrect value for last_msg_.obs[4].L.i, expected -36797, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1985374378) - << "incorrect value for last_msg_.obs[4].P, expected 1985374378, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 56) - << "incorrect value for last_msg_.obs[4].cn0, expected 56, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 22736) - << "incorrect value for last_msg_.obs[4].lock, expected 22736, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].prn, 30) - << "incorrect value for last_msg_.obs[4].prn, expected 30, is " - << last_msg_.obs[4].prn; -} -class Test_auto_check_sbp_observation_msgObsDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgObsDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_observation_msgObsDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_observation_msgObsDepA1() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 407084600); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 1); + + assign(test_msg_.obs[0].L.f, 147); + assign(test_msg_.obs[0].L.i, 8294); + assign(test_msg_.obs[0].P, 1973695572); + assign(test_msg_.obs[0].cn0, 62); + assign(test_msg_.obs[0].lock, 64062); + assign(test_msg_.obs[0].prn, 31); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_obs_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_obs_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_observation_msgObsDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 69, 0, 195, 4, 72, 40, 163, 68, 24, 46, 7, 16, 132, - 107, 217, 121, 14, 148, 255, 255, 1, 44, 175, 147, 0, 129, 66, - 200, 125, 148, 29, 254, 255, 153, 41, 14, 177, 3, 128, 178, 248, - 136, 143, 66, 254, 255, 222, 18, 184, 133, 13, 158, 53, 178, 134, - 42, 27, 2, 0, 237, 30, 33, 96, 22, 38, 83, 86, 118, 168, - 111, 255, 255, 45, 56, 208, 88, 30, 1, 175, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_obs_dep_a_t test_msg{}; - test_msg.header.n_obs = 16; - test_msg.header.t.tow = 407151400; - test_msg.header.t.wn = 1838; - test_msg.n_obs = 5; - - test_msg.obs[0].L.f = 1; - test_msg.obs[0].L.i = -27634; - test_msg.obs[0].P = 2044291972; - test_msg.obs[0].cn0 = 44; - test_msg.obs[0].lock = 37807; - test_msg.obs[0].prn = 0; - - test_msg.obs[1].L.f = 153; - test_msg.obs[1].L.i = -123500; - test_msg.obs[1].P = 2110276225; - test_msg.obs[1].cn0 = 41; - test_msg.obs[1].lock = 45326; - test_msg.obs[1].prn = 3; - - test_msg.obs[2].L.f = 222; - test_msg.obs[2].L.i = -114033; - test_msg.obs[2].P = 2298000000; - test_msg.obs[2].cn0 = 18; - test_msg.obs[2].lock = 34232; - test_msg.obs[2].prn = 13; - - test_msg.obs[3].L.f = 237; - test_msg.obs[3].L.i = 138026; - test_msg.obs[3].P = 2259826078; - test_msg.obs[3].cn0 = 30; - test_msg.obs[3].lock = 24609; - test_msg.obs[3].prn = 22; - - test_msg.obs[4].L.f = 45; - test_msg.obs[4].L.i = -36952; - test_msg.obs[4].P = 1985368870; - test_msg.obs[4].cn0 = 56; - test_msg.obs[4].lock = 22736; - test_msg.obs[4].prn = 30; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.n_obs, 16) - << "incorrect value for last_msg_.header.n_obs, expected 16, is " - << last_msg_.header.n_obs; - EXPECT_EQ(last_msg_.header.t.tow, 407151400) - << "incorrect value for last_msg_.header.t.tow, expected 407151400, is " - << last_msg_.header.t.tow; - EXPECT_EQ(last_msg_.header.t.wn, 1838) - << "incorrect value for last_msg_.header.t.wn, expected 1838, is " - << last_msg_.header.t.wn; - EXPECT_EQ(last_msg_.n_obs, 5) - << "incorrect value for last_msg_.n_obs, expected 5, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.obs[0].L.f, 1) - << "incorrect value for last_msg_.obs[0].L.f, expected 1, is " - << last_msg_.obs[0].L.f; - EXPECT_EQ(last_msg_.obs[0].L.i, -27634) - << "incorrect value for last_msg_.obs[0].L.i, expected -27634, is " - << last_msg_.obs[0].L.i; - EXPECT_EQ(last_msg_.obs[0].P, 2044291972) - << "incorrect value for last_msg_.obs[0].P, expected 2044291972, is " - << last_msg_.obs[0].P; - EXPECT_EQ(last_msg_.obs[0].cn0, 44) - << "incorrect value for last_msg_.obs[0].cn0, expected 44, is " - << last_msg_.obs[0].cn0; - EXPECT_EQ(last_msg_.obs[0].lock, 37807) - << "incorrect value for last_msg_.obs[0].lock, expected 37807, is " - << last_msg_.obs[0].lock; - EXPECT_EQ(last_msg_.obs[0].prn, 0) - << "incorrect value for last_msg_.obs[0].prn, expected 0, is " - << last_msg_.obs[0].prn; - EXPECT_EQ(last_msg_.obs[1].L.f, 153) - << "incorrect value for last_msg_.obs[1].L.f, expected 153, is " - << last_msg_.obs[1].L.f; - EXPECT_EQ(last_msg_.obs[1].L.i, -123500) - << "incorrect value for last_msg_.obs[1].L.i, expected -123500, is " - << last_msg_.obs[1].L.i; - EXPECT_EQ(last_msg_.obs[1].P, 2110276225) - << "incorrect value for last_msg_.obs[1].P, expected 2110276225, is " - << last_msg_.obs[1].P; - EXPECT_EQ(last_msg_.obs[1].cn0, 41) - << "incorrect value for last_msg_.obs[1].cn0, expected 41, is " - << last_msg_.obs[1].cn0; - EXPECT_EQ(last_msg_.obs[1].lock, 45326) - << "incorrect value for last_msg_.obs[1].lock, expected 45326, is " - << last_msg_.obs[1].lock; - EXPECT_EQ(last_msg_.obs[1].prn, 3) - << "incorrect value for last_msg_.obs[1].prn, expected 3, is " - << last_msg_.obs[1].prn; - EXPECT_EQ(last_msg_.obs[2].L.f, 222) - << "incorrect value for last_msg_.obs[2].L.f, expected 222, is " - << last_msg_.obs[2].L.f; - EXPECT_EQ(last_msg_.obs[2].L.i, -114033) - << "incorrect value for last_msg_.obs[2].L.i, expected -114033, is " - << last_msg_.obs[2].L.i; - EXPECT_EQ(last_msg_.obs[2].P, 2298000000) - << "incorrect value for last_msg_.obs[2].P, expected 2298000000, is " - << last_msg_.obs[2].P; - EXPECT_EQ(last_msg_.obs[2].cn0, 18) - << "incorrect value for last_msg_.obs[2].cn0, expected 18, is " - << last_msg_.obs[2].cn0; - EXPECT_EQ(last_msg_.obs[2].lock, 34232) - << "incorrect value for last_msg_.obs[2].lock, expected 34232, is " - << last_msg_.obs[2].lock; - EXPECT_EQ(last_msg_.obs[2].prn, 13) - << "incorrect value for last_msg_.obs[2].prn, expected 13, is " - << last_msg_.obs[2].prn; - EXPECT_EQ(last_msg_.obs[3].L.f, 237) - << "incorrect value for last_msg_.obs[3].L.f, expected 237, is " - << last_msg_.obs[3].L.f; - EXPECT_EQ(last_msg_.obs[3].L.i, 138026) - << "incorrect value for last_msg_.obs[3].L.i, expected 138026, is " - << last_msg_.obs[3].L.i; - EXPECT_EQ(last_msg_.obs[3].P, 2259826078) - << "incorrect value for last_msg_.obs[3].P, expected 2259826078, is " - << last_msg_.obs[3].P; - EXPECT_EQ(last_msg_.obs[3].cn0, 30) - << "incorrect value for last_msg_.obs[3].cn0, expected 30, is " - << last_msg_.obs[3].cn0; - EXPECT_EQ(last_msg_.obs[3].lock, 24609) - << "incorrect value for last_msg_.obs[3].lock, expected 24609, is " - << last_msg_.obs[3].lock; - EXPECT_EQ(last_msg_.obs[3].prn, 22) - << "incorrect value for last_msg_.obs[3].prn, expected 22, is " - << last_msg_.obs[3].prn; - EXPECT_EQ(last_msg_.obs[4].L.f, 45) - << "incorrect value for last_msg_.obs[4].L.f, expected 45, is " - << last_msg_.obs[4].L.f; - EXPECT_EQ(last_msg_.obs[4].L.i, -36952) - << "incorrect value for last_msg_.obs[4].L.i, expected -36952, is " - << last_msg_.obs[4].L.i; - EXPECT_EQ(last_msg_.obs[4].P, 1985368870) - << "incorrect value for last_msg_.obs[4].P, expected 1985368870, is " - << last_msg_.obs[4].P; - EXPECT_EQ(last_msg_.obs[4].cn0, 56) - << "incorrect value for last_msg_.obs[4].cn0, expected 56, is " - << last_msg_.obs[4].cn0; - EXPECT_EQ(last_msg_.obs[4].lock, 22736) - << "incorrect value for last_msg_.obs[4].lock, expected 22736, is " - << last_msg_.obs[4].lock; - EXPECT_EQ(last_msg_.obs[4].prn, 30) - << "incorrect value for last_msg_.obs[4].prn, expected 30, is " - << last_msg_.obs[4].prn; -} + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xeea; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 69, 0, 195, 4, 20, 56, 158, 67, 24, 46, 7, 33, 84, + 52, 164, 117, 102, 32, 0, 0, 147, 62, 62, 250, 31, 234, 14, + }; + uint8_t encoded_payload_[20] = { + 56, 158, 67, 24, 46, 7, 33, 84, 52, 164, + 117, 102, 32, 0, 0, 147, 62, 62, 250, 31, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgObsDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgObsDepA2() { + assign(test_msg_.header.n_obs, 32); + assign(test_msg_.header.t.tow, 407084800); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 7); + + assign(test_msg_.obs[0].L.f, 141); + assign(test_msg_.obs[0].L.i, -36207); + assign(test_msg_.obs[0].P, 2046415136); + assign(test_msg_.obs[0].cn0, 45); + assign(test_msg_.obs[0].lock, 55875); + assign(test_msg_.obs[0].prn, 0); + + assign(test_msg_.obs[1].L.f, 159); + assign(test_msg_.obs[1].L.i, 203599); + assign(test_msg_.obs[1].P, 2084995249); + assign(test_msg_.obs[1].cn0, 44); + assign(test_msg_.obs[1].lock, 40376); + assign(test_msg_.obs[1].prn, 2); + + assign(test_msg_.obs[2].L.f, 77); + assign(test_msg_.obs[2].L.i, -178769); + assign(test_msg_.obs[2].P, 2110097211); + assign(test_msg_.obs[2].cn0, 40); + assign(test_msg_.obs[2].lock, 14148); + assign(test_msg_.obs[2].prn, 3); + + assign(test_msg_.obs[3].L.f, 20); + assign(test_msg_.obs[3].L.i, -137807); + assign(test_msg_.obs[3].P, 2208476371); + assign(test_msg_.obs[3].cn0, 31); + assign(test_msg_.obs[3].lock, 4129); + assign(test_msg_.obs[3].prn, 10); + + assign(test_msg_.obs[4].L.f, 94); + assign(test_msg_.obs[4].L.i, -168076); + assign(test_msg_.obs[4].P, 2298000000); + assign(test_msg_.obs[4].cn0, 21); + assign(test_msg_.obs[4].lock, 18218); + assign(test_msg_.obs[4].prn, 13); + + assign(test_msg_.obs[5].L.f, 214); + assign(test_msg_.obs[5].L.i, 210469); + assign(test_msg_.obs[5].P, 2266082742); + assign(test_msg_.obs[5].cn0, 27); + assign(test_msg_.obs[5].lock, 63852); + assign(test_msg_.obs[5].prn, 22); + + assign(test_msg_.obs[6].L.f, 129); + assign(test_msg_.obs[6].L.i, -53264); + assign(test_msg_.obs[6].P, 1987187803); + assign(test_msg_.obs[6].cn0, 52); + assign(test_msg_.obs[6].lock, 15074); + assign(test_msg_.obs[6].prn, 30); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x77c8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 98; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[98 + 8] = { + 85, 69, 0, 195, 4, 98, 0, 159, 67, 24, 46, 7, 32, 32, + 209, 249, 121, 145, 114, 255, 255, 141, 45, 67, 218, 0, 177, 128, + 70, 124, 79, 27, 3, 0, 159, 44, 184, 157, 2, 59, 135, 197, + 125, 175, 69, 253, 255, 77, 40, 68, 55, 3, 211, 172, 162, 131, + 177, 229, 253, 255, 20, 31, 33, 16, 10, 128, 178, 248, 136, 116, + 111, 253, 255, 94, 21, 42, 71, 13, 182, 173, 17, 135, 37, 54, + 3, 0, 214, 27, 108, 249, 22, 91, 20, 114, 118, 240, 47, 255, + 255, 129, 52, 226, 58, 30, 200, 119, + }; + uint8_t encoded_payload_[98] = { + 0, 159, 67, 24, 46, 7, 32, 32, 209, 249, 121, 145, 114, 255, + 255, 141, 45, 67, 218, 0, 177, 128, 70, 124, 79, 27, 3, 0, + 159, 44, 184, 157, 2, 59, 135, 197, 125, 175, 69, 253, 255, 77, + 40, 68, 55, 3, 211, 172, 162, 131, 177, 229, 253, 255, 20, 31, + 33, 16, 10, 128, 178, 248, 136, 116, 111, 253, 255, 94, 21, 42, + 71, 13, 182, 173, 17, 135, 37, 54, 3, 0, 214, 27, 108, 249, + 22, 91, 20, 114, 118, 240, 47, 255, 255, 129, 52, 226, 58, 30, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + + for (uint8_t i = 0; i < 98; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].prn, greater.obs[1].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].prn, greater.obs[2].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].prn, greater.obs[3].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].prn, greater.obs[4].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.f, greater.obs[5].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].L.i, greater.obs[5].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].P, greater.obs[5].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].cn0, greater.obs[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].lock, greater.obs[5].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[5].prn, greater.obs[5].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.f, greater.obs[6].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].L.i, greater.obs[6].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].P, greater.obs[6].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].cn0, greater.obs[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].lock, greater.obs[6].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[6].prn, greater.obs[6].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[98]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 98); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 98), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 98); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgObsDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgObsDepA3() { + assign(test_msg_.header.n_obs, 33); + assign(test_msg_.header.t.tow, 407084800); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 1); + + assign(test_msg_.obs[0].L.f, 222); + assign(test_msg_.obs[0].L.i, 8312); + assign(test_msg_.obs[0].P, 1973687089); + assign(test_msg_.obs[0].cn0, 63); + assign(test_msg_.obs[0].lock, 64062); + assign(test_msg_.obs[0].prn, 31); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xe70b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { + 85, 69, 0, 195, 4, 20, 0, 159, 67, 24, 46, 7, 33, 49, + 19, 164, 117, 120, 32, 0, 0, 222, 63, 62, 250, 31, 11, 231, + }; + uint8_t encoded_payload_[20] = { + 0, 159, 67, 24, 46, 7, 33, 49, 19, 164, + 117, 120, 32, 0, 0, 222, 63, 62, 250, 31, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgObsDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgObsDepA4() { + assign(test_msg_.header.n_obs, 16); + assign(test_msg_.header.t.tow, 407151200); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 5); + + assign(test_msg_.obs[0].L.f, 189); + assign(test_msg_.obs[0].L.i, -27527); + assign(test_msg_.obs[0].P, 2044298327); + assign(test_msg_.obs[0].cn0, 43); + assign(test_msg_.obs[0].lock, 37807); + assign(test_msg_.obs[0].prn, 0); + + assign(test_msg_.obs[1].L.f, 1); + assign(test_msg_.obs[1].L.i, -123030); + assign(test_msg_.obs[1].P, 2110275716); + assign(test_msg_.obs[1].cn0, 41); + assign(test_msg_.obs[1].lock, 45326); + assign(test_msg_.obs[1].prn, 3); + + assign(test_msg_.obs[2].L.f, 166); + assign(test_msg_.obs[2].L.i, -113594); + assign(test_msg_.obs[2].P, 2298000000); + assign(test_msg_.obs[2].cn0, 18); + assign(test_msg_.obs[2].lock, 34232); + assign(test_msg_.obs[2].prn, 13); + + assign(test_msg_.obs[3].L.f, 249); + assign(test_msg_.obs[3].L.i, 137478); + assign(test_msg_.obs[3].P, 2259844888); + assign(test_msg_.obs[3].cn0, 28); + assign(test_msg_.obs[3].lock, 24609); + assign(test_msg_.obs[3].prn, 22); + + assign(test_msg_.obs[4].L.f, 203); + assign(test_msg_.obs[4].L.i, -36797); + assign(test_msg_.obs[4].P, 1985374378); + assign(test_msg_.obs[4].cn0, 56); + assign(test_msg_.obs[4].lock, 22736); + assign(test_msg_.obs[4].prn, 30); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6b2b; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 72; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[72 + 8] = { + 85, 69, 0, 195, 4, 72, 96, 162, 68, 24, 46, 7, 16, 87, + 132, 217, 121, 121, 148, 255, 255, 189, 43, 175, 147, 0, 132, 64, + 200, 125, 106, 31, 254, 255, 1, 41, 14, 177, 3, 128, 178, 248, + 136, 70, 68, 254, 255, 166, 18, 184, 133, 13, 24, 127, 178, 134, + 6, 25, 2, 0, 249, 28, 33, 96, 22, 170, 104, 86, 118, 67, + 112, 255, 255, 203, 56, 208, 88, 30, 43, 107, + }; + uint8_t encoded_payload_[72] = { + 96, 162, 68, 24, 46, 7, 16, 87, 132, 217, 121, 121, 148, 255, 255, + 189, 43, 175, 147, 0, 132, 64, 200, 125, 106, 31, 254, 255, 1, 41, + 14, 177, 3, 128, 178, 248, 136, 70, 68, 254, 255, 166, 18, 184, 133, + 13, 24, 127, 178, 134, 6, 25, 2, 0, 249, 28, 33, 96, 22, 170, + 104, 86, 118, 67, 112, 255, 255, 203, 56, 208, 88, 30, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + + for (uint8_t i = 0; i < 72; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].prn, greater.obs[1].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].prn, greater.obs[2].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].prn, greater.obs[3].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].prn, greater.obs[4].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_observation_msgObsDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_observation_msgObsDepA5() { + assign(test_msg_.header.n_obs, 16); + assign(test_msg_.header.t.tow, 407151400); + assign(test_msg_.header.t.wn, 1838); + assign(test_msg_.n_obs, 5); + + assign(test_msg_.obs[0].L.f, 1); + assign(test_msg_.obs[0].L.i, -27634); + assign(test_msg_.obs[0].P, 2044291972); + assign(test_msg_.obs[0].cn0, 44); + assign(test_msg_.obs[0].lock, 37807); + assign(test_msg_.obs[0].prn, 0); + + assign(test_msg_.obs[1].L.f, 153); + assign(test_msg_.obs[1].L.i, -123500); + assign(test_msg_.obs[1].P, 2110276225); + assign(test_msg_.obs[1].cn0, 41); + assign(test_msg_.obs[1].lock, 45326); + assign(test_msg_.obs[1].prn, 3); + + assign(test_msg_.obs[2].L.f, 222); + assign(test_msg_.obs[2].L.i, -114033); + assign(test_msg_.obs[2].P, 2298000000); + assign(test_msg_.obs[2].cn0, 18); + assign(test_msg_.obs[2].lock, 34232); + assign(test_msg_.obs[2].prn, 13); + + assign(test_msg_.obs[3].L.f, 237); + assign(test_msg_.obs[3].L.i, 138026); + assign(test_msg_.obs[3].P, 2259826078); + assign(test_msg_.obs[3].cn0, 30); + assign(test_msg_.obs[3].lock, 24609); + assign(test_msg_.obs[3].prn, 22); + + assign(test_msg_.obs[4].L.f, 45); + assign(test_msg_.obs[4].L.i, -36952); + assign(test_msg_.obs[4].P, 1985368870); + assign(test_msg_.obs[4].cn0, 56); + assign(test_msg_.obs[4].lock, 22736); + assign(test_msg_.obs[4].prn, 30); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_obs_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgObsDepA, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_obs_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgObsDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->obs_dep_a, sizeof(msg->obs_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_obs_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.obs_dep_a, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgObsDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xaf01; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 72; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_obs_dep_a_t &lesser, + const sbp_msg_obs_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_obs_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_obs_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_obs_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgObsDepA, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgObsDepA, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_obs_dep_a_t test_msg_{}; + uint8_t encoded_frame_[72 + 8] = { + 85, 69, 0, 195, 4, 72, 40, 163, 68, 24, 46, 7, 16, 132, + 107, 217, 121, 14, 148, 255, 255, 1, 44, 175, 147, 0, 129, 66, + 200, 125, 148, 29, 254, 255, 153, 41, 14, 177, 3, 128, 178, 248, + 136, 143, 66, 254, 255, 222, 18, 184, 133, 13, 158, 53, 178, 134, + 42, 27, 2, 0, 237, 30, 33, 96, 22, 38, 83, 86, 118, 168, + 111, 255, 255, 45, 56, 208, 88, 30, 1, 175, + }; + uint8_t encoded_payload_[72] = { + 40, 163, 68, 24, 46, 7, 16, 132, 107, 217, 121, 14, 148, 255, 255, + 1, 44, 175, 147, 0, 129, 66, 200, 125, 148, 29, 254, 255, 153, 41, + 14, 177, 3, 128, 178, 248, 136, 143, 66, 254, 255, 222, 18, 184, 133, + 13, 158, 53, 178, 134, 42, 27, 2, 0, 237, 30, 33, 96, 22, 38, + 83, 86, 118, 168, 111, 255, 255, 45, 56, 208, 88, 30, + }; +}; + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_obs_dep_a_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgObsDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgObsDepA, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + + EXPECT_EQ( + sbp_msg_obs_dep_a_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + + for (uint8_t i = 0; i < 72; i++) { + EXPECT_EQ(sbp_msg_obs_dep_a_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgObsDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + return sbp_msg_obs_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_obs_dep_a_t t{}; + t.n_obs = 1; + return sbp_msg_obs_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_obs_dep_a_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_obs_dep_a_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgObsDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.n_obs, greater.header.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.tow, greater.header.t.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.header.t.wn, greater.header.t.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.f, greater.obs[0].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].L.i, greater.obs[0].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].P, greater.obs[0].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].cn0, greater.obs[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].lock, greater.obs[0].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[0].prn, greater.obs[0].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.f, greater.obs[1].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].L.i, greater.obs[1].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].P, greater.obs[1].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].cn0, greater.obs[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].lock, greater.obs[1].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[1].prn, greater.obs[1].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.f, greater.obs[2].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].L.i, greater.obs[2].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].P, greater.obs[2].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].cn0, greater.obs[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].lock, greater.obs[2].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[2].prn, greater.obs[2].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.f, greater.obs[3].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].L.i, greater.obs[3].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].P, greater.obs[3].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].cn0, greater.obs[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].lock, greater.obs[3].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[3].prn, greater.obs[3].prn); + comparison_tests(lesser, greater); + } + + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.f, greater.obs[4].L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].L.i, greater.obs[4].L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].P, greater.obs[4].P); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].cn0, greater.obs[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].lock, greater.obs[4].lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_obs_dep_a_t lesser = info.test_msg; + sbp_msg_obs_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.obs[4].prn, greater.obs[4].prn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgObsDepA); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_OBS_DEP_A"); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_obs_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_obs_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.obs_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.obs_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[72]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 72); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 72), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_obs_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 72); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgObsDepA, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_observation_msgObsDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgObsDepA, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_orientation_MsgAngularRate.cc b/c/test/cpp/auto_check_sbp_orientation_MsgAngularRate.cc index e878673879..3f1985cb8f 100644 --- a/c/test/cpp/auto_check_sbp_orientation_MsgAngularRate.cc +++ b/c/test/cpp/auto_check_sbp_orientation_MsgAngularRate.cc @@ -16,98 +16,599 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_orientation_MsgAngularRate0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_orientation_MsgAngularRate0 : public ::testing::Test { public: - Test_auto_check_sbp_orientation_MsgAngularRate0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_orientation_MsgAngularRate0() { + assign(test_msg_.flags, 0); + assign(test_msg_.tow, 2); + assign(test_msg_.x, 2); + assign(test_msg_.y, 5); + assign(test_msg_.z, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_angular_rate_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_angular_rate_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgAngularRate, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_angular_rate_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgAngularRate); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->angular_rate, + sizeof(msg->angular_rate)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_angular_rate_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.angular_rate, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgAngularRate); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x4658; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 17; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_angular_rate_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_angular_rate_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_angular_rate_t &lesser, + const sbp_msg_angular_rate_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_angular_rate_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_angular_rate_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_angular_rate_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_angular_rate_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgAngularRate, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgAngularRate, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgAngularRate, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgAngularRate, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_orientation_MsgAngularRate0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_angular_rate_t test_msg_{}; + uint8_t encoded_frame_[17 + 8] = { 85, 34, 2, 66, 0, 17, 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, 88, 70, }; + uint8_t encoded_payload_[17] = { + 2, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 2, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_angular_rate_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgAngularRate, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_angular_rate_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgAngularRate, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} - sbp_msg_angular_rate_t test_msg{}; - test_msg.flags = 0; - test_msg.tow = 2; - test_msg.x = 2; - test_msg.y = 5; - test_msg.z = 2; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.tow, 2) - << "incorrect value for last_msg_.tow, expected 2, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.x, 2) - << "incorrect value for last_msg_.x, expected 2, is " << last_msg_.x; - EXPECT_EQ(last_msg_.y, 5) - << "incorrect value for last_msg_.y, expected 5, is " << last_msg_.y; - EXPECT_EQ(last_msg_.z, 2) - << "incorrect value for last_msg_.z, expected 2, is " << last_msg_.z; +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + EXPECT_EQ(sbp_msg_angular_rate_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); } +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + for (uint8_t i = 0; i < 17; i++) { + EXPECT_EQ(sbp_msg_angular_rate_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_angular_rate_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_angular_rate_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgAngularRate, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_angular_rate_t msg{}; + + EXPECT_EQ(sbp_msg_angular_rate_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_angular_rate_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_angular_rate_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_angular_rate_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgAngularRate, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_angular_rate_t lesser = info.test_msg; + sbp_msg_angular_rate_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_angular_rate_t lesser = info.test_msg; + sbp_msg_angular_rate_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_angular_rate_t lesser = info.test_msg; + sbp_msg_angular_rate_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_angular_rate_t lesser = info.test_msg; + sbp_msg_angular_rate_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_angular_rate_t lesser = info.test_msg; + sbp_msg_angular_rate_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgAngularRate); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ANGULAR_RATE"); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_angular_rate_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_angular_rate_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.angular_rate, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.angular_rate, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_angular_rate_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgAngularRate, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgAngularRate0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgAngularRate, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_orientation_MsgOrientEuler.cc b/c/test/cpp/auto_check_sbp_orientation_MsgOrientEuler.cc index 7f8b87c3ad..21016d8b9f 100644 --- a/c/test/cpp/auto_check_sbp_orientation_MsgOrientEuler.cc +++ b/c/test/cpp/auto_check_sbp_orientation_MsgOrientEuler.cc @@ -16,112 +16,621 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_orientation_MsgOrientEuler0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_orientation_MsgOrientEuler0 : public ::testing::Test { public: - Test_auto_check_sbp_orientation_MsgOrientEuler0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_orientation_MsgOrientEuler0() { + assign(test_msg_.flags, 3); + assign(test_msg_.pitch, 2); + assign(test_msg_.pitch_accuracy, 3.0); + assign(test_msg_.roll, 1); + assign(test_msg_.roll_accuracy, 7.0); + assign(test_msg_.tow, 1); + assign(test_msg_.yaw, 8); + assign(test_msg_.yaw_accuracy, 7.0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_orient_euler_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_orient_euler_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgOrientEuler, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_orient_euler_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgOrientEuler); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->orient_euler, + sizeof(msg->orient_euler)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_orient_euler_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.orient_euler, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgOrientEuler); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xe22c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 29; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_orient_euler_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_orient_euler_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_orient_euler_t &lesser, + const sbp_msg_orient_euler_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_orient_euler_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_orient_euler_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_orient_euler_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_orient_euler_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgOrientEuler, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgOrientEuler, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgOrientEuler, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgOrientEuler, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_orientation_MsgOrientEuler0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_orient_euler_t test_msg_{}; + uint8_t encoded_frame_[29 + 8] = { 85, 33, 2, 66, 0, 29, 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 224, 64, 0, 0, 64, 64, 0, 0, 224, 64, 3, 44, 226, }; + uint8_t encoded_payload_[29] = { + 1, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, + 0, 0, 0, 224, 64, 0, 0, 64, 64, 0, 0, 224, 64, 3, + }; +}; + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_orient_euler_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgOrientEuler, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_orient_euler_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgOrientEuler, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + + EXPECT_EQ(sbp_msg_orient_euler_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + + for (uint8_t i = 0; i < 29; i++) { + EXPECT_EQ(sbp_msg_orient_euler_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_orient_euler_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_orient_euler_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgOrientEuler, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_orient_euler_t test_msg{}; - test_msg.flags = 3; - test_msg.pitch = 2; - test_msg.pitch_accuracy = 3.0; - test_msg.roll = 1; - test_msg.roll_accuracy = 7.0; - test_msg.tow = 1; - test_msg.yaw = 8; - test_msg.yaw_accuracy = 7.0; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 3) - << "incorrect value for last_msg_.flags, expected 3, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.pitch, 2) - << "incorrect value for last_msg_.pitch, expected 2, is " - << last_msg_.pitch; - EXPECT_LT((last_msg_.pitch_accuracy * 100 - 3.0 * 100), 0.05) - << "incorrect value for last_msg_.pitch_accuracy, expected 3.0, is " - << last_msg_.pitch_accuracy; - EXPECT_EQ(last_msg_.roll, 1) - << "incorrect value for last_msg_.roll, expected 1, is " - << last_msg_.roll; - EXPECT_LT((last_msg_.roll_accuracy * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.roll_accuracy, expected 7.0, is " - << last_msg_.roll_accuracy; - EXPECT_EQ(last_msg_.tow, 1) - << "incorrect value for last_msg_.tow, expected 1, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.yaw, 8) - << "incorrect value for last_msg_.yaw, expected 8, is " << last_msg_.yaw; - EXPECT_LT((last_msg_.yaw_accuracy * 100 - 7.0 * 100), 0.05) - << "incorrect value for last_msg_.yaw_accuracy, expected 7.0, is " - << last_msg_.yaw_accuracy; +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_orient_euler_t msg{}; + + EXPECT_EQ(sbp_msg_orient_euler_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_orient_euler_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_orient_euler_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_orient_euler_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgOrientEuler, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.pitch, greater.pitch); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.pitch_accuracy, greater.pitch_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.roll, greater.roll); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.roll_accuracy, greater.roll_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.yaw, greater.yaw); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_euler_t lesser = info.test_msg; + sbp_msg_orient_euler_t greater = info.test_msg; + make_lesser_greater(lesser.yaw_accuracy, greater.yaw_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgOrientEuler); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ORIENT_EULER"); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_orient_euler_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_orient_euler_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.orient_euler, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.orient_euler, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_orient_euler_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgOrientEuler, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientEuler0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgOrientEuler, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_orientation_MsgOrientQuat.cc b/c/test/cpp/auto_check_sbp_orientation_MsgOrientQuat.cc index 0223ee72d1..1f564b6e83 100644 --- a/c/test/cpp/auto_check_sbp_orientation_MsgOrientQuat.cc +++ b/c/test/cpp/auto_check_sbp_orientation_MsgOrientQuat.cc @@ -16,118 +16,633 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_orientation_MsgOrientQuat0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_orientation_MsgOrientQuat0 : public ::testing::Test { public: - Test_auto_check_sbp_orientation_MsgOrientQuat0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_orientation_MsgOrientQuat0() { + assign(test_msg_.flags, 1); + assign(test_msg_.tow, 0); + assign(test_msg_.w, 3); + assign(test_msg_.w_accuracy, 3.0); + assign(test_msg_.x, 7); + assign(test_msg_.x_accuracy, 4.0); + assign(test_msg_.y, 8); + assign(test_msg_.y_accuracy, 8.0); + assign(test_msg_.z, 4); + assign(test_msg_.z_accuracy, 3.0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_orient_quat_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_orient_quat_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgOrientQuat, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_orient_quat_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgOrientQuat); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->orient_quat, sizeof(msg->orient_quat)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_orient_quat_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.orient_quat, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgOrientQuat); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x6ba; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 37; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_orient_quat_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_orient_quat_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_orient_quat_t &lesser, + const sbp_msg_orient_quat_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_orient_quat_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_orient_quat_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_orient_quat_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_orient_quat_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgOrientQuat, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgOrientQuat, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgOrientQuat, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgOrientQuat, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_orientation_MsgOrientQuat0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_orient_quat_t test_msg_{}; + uint8_t encoded_frame_[37 + 8] = { 85, 32, 2, 66, 0, 37, 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, 0, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 0, 65, 0, 0, 64, 64, 1, 186, 6, }; + uint8_t encoded_payload_[37] = { + 0, 0, 0, 0, 3, 0, 0, 0, 7, 0, 0, 0, 8, 0, 0, 0, 4, 0, 0, + 0, 0, 0, 64, 64, 0, 0, 128, 64, 0, 0, 0, 65, 0, 0, 64, 64, 1, + }; +}; + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_orient_quat_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgOrientQuat, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[37]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_orient_quat_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 37); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 37), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgOrientQuat, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 37); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 37), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[37]; + + EXPECT_EQ( + sbp_msg_orient_quat_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 37), 0); +} +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[37]; + + for (uint8_t i = 0; i < 37; i++) { + EXPECT_EQ(sbp_msg_orient_quat_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_orient_quat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_orient_quat_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 37); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgOrientQuat, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 37); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_orient_quat_t msg{}; - sbp_msg_orient_quat_t test_msg{}; - test_msg.flags = 1; - test_msg.tow = 0; - test_msg.w = 3; - test_msg.w_accuracy = 3.0; - test_msg.x = 7; - test_msg.x_accuracy = 4.0; - test_msg.y = 8; - test_msg.y_accuracy = 8.0; - test_msg.z = 4; - test_msg.z_accuracy = 3.0; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.tow, 0) - << "incorrect value for last_msg_.tow, expected 0, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.w, 3) - << "incorrect value for last_msg_.w, expected 3, is " << last_msg_.w; - EXPECT_LT((last_msg_.w_accuracy * 100 - 3.0 * 100), 0.05) - << "incorrect value for last_msg_.w_accuracy, expected 3.0, is " - << last_msg_.w_accuracy; - EXPECT_EQ(last_msg_.x, 7) - << "incorrect value for last_msg_.x, expected 7, is " << last_msg_.x; - EXPECT_LT((last_msg_.x_accuracy * 100 - 4.0 * 100), 0.05) - << "incorrect value for last_msg_.x_accuracy, expected 4.0, is " - << last_msg_.x_accuracy; - EXPECT_EQ(last_msg_.y, 8) - << "incorrect value for last_msg_.y, expected 8, is " << last_msg_.y; - EXPECT_LT((last_msg_.y_accuracy * 100 - 8.0 * 100), 0.05) - << "incorrect value for last_msg_.y_accuracy, expected 8.0, is " - << last_msg_.y_accuracy; - EXPECT_EQ(last_msg_.z, 4) - << "incorrect value for last_msg_.z, expected 4, is " << last_msg_.z; - EXPECT_LT((last_msg_.z_accuracy * 100 - 3.0 * 100), 0.05) - << "incorrect value for last_msg_.z_accuracy, expected 3.0, is " - << last_msg_.z_accuracy; + EXPECT_EQ(sbp_msg_orient_quat_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_orient_quat_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_orient_quat_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_orient_quat_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgOrientQuat, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.w, greater.w); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.w_accuracy, greater.w_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.x, greater.x); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.x_accuracy, greater.x_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.y, greater.y); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.y_accuracy, greater.y_accuracy); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.z, greater.z); + comparison_tests(lesser, greater); + } + { + sbp_msg_orient_quat_t lesser = info.test_msg; + sbp_msg_orient_quat_t greater = info.test_msg; + make_lesser_greater(lesser.z_accuracy, greater.z_accuracy); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgOrientQuat); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ORIENT_QUAT"); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_orient_quat_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_orient_quat_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.orient_quat, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.orient_quat, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[37]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 37); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 37), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_orient_quat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 37); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgOrientQuat, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_orientation_MsgOrientQuat0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgOrientQuat, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgDeviceMonitor.cc b/c/test/cpp/auto_check_sbp_piksi_MsgDeviceMonitor.cc index 56233bcd57..39eee39274 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgDeviceMonitor.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgDeviceMonitor.cc @@ -16,486 +16,2954 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgDeviceMonitor0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgDeviceMonitor0 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgDeviceMonitor0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgDeviceMonitor0() { + assign(test_msg_.cpu_temperature, 6165); + assign(test_msg_.cpu_vaux, 1789); + assign(test_msg_.cpu_vint, 987); + assign(test_msg_.dev_vin, -9999); + assign(test_msg_.fe_temperature, 4776); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_device_monitor_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDeviceMonitor, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDeviceMonitor); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->device_monitor, + sizeof(msg->device_monitor)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_device_monitor_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.device_monitor, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDeviceMonitor); + info.sender_id = 16991; + info.preamble = 0x55; + info.crc = 0xe9cf; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_device_monitor_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_device_monitor_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_device_monitor_t &lesser, + const sbp_msg_device_monitor_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_device_monitor_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_device_monitor_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_device_monitor_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_device_monitor_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_piksi_MsgDeviceMonitor0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_device_monitor_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { 85, 181, 0, 95, 66, 10, 241, 216, 219, 3, 253, 6, 21, 24, 168, 18, 207, 233, }; + uint8_t encoded_payload_[10] = { + 241, 216, 219, 3, 253, 6, 21, 24, 168, 18, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_device_monitor_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgDeviceMonitor, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDeviceMonitor, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ( + sbp_msg_device_monitor_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDeviceMonitor, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_device_monitor_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDeviceMonitor, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_temperature, greater.cpu_temperature); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vaux, greater.cpu_vaux); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vint, greater.cpu_vint); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.dev_vin, greater.dev_vin); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.fe_temperature, greater.fe_temperature); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDeviceMonitor); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DEVICE_MONITOR"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_device_monitor_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_device_monitor_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.device_monitor, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.device_monitor, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; - sbp_msg_device_monitor_t test_msg{}; - test_msg.cpu_temperature = 6165; - test_msg.cpu_vaux = 1789; - test_msg.cpu_vint = 987; - test_msg.dev_vin = -9999; - test_msg.fe_temperature = 4776; - - EXPECT_EQ(send_message(16991, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 16991); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu_temperature, 6165) - << "incorrect value for last_msg_.cpu_temperature, expected 6165, is " - << last_msg_.cpu_temperature; - EXPECT_EQ(last_msg_.cpu_vaux, 1789) - << "incorrect value for last_msg_.cpu_vaux, expected 1789, is " - << last_msg_.cpu_vaux; - EXPECT_EQ(last_msg_.cpu_vint, 987) - << "incorrect value for last_msg_.cpu_vint, expected 987, is " - << last_msg_.cpu_vint; - EXPECT_EQ(last_msg_.dev_vin, -9999) - << "incorrect value for last_msg_.dev_vin, expected -9999, is " - << last_msg_.dev_vin; - EXPECT_EQ(last_msg_.fe_temperature, 4776) - << "incorrect value for last_msg_.fe_temperature, expected 4776, is " - << last_msg_.fe_temperature; -} -class Test_auto_check_sbp_piksi_MsgDeviceMonitor1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDeviceMonitor, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDeviceMonitor, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgDeviceMonitor1 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgDeviceMonitor1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgDeviceMonitor1() { + assign(test_msg_.cpu_temperature, 6168); + assign(test_msg_.cpu_vaux, 1790); + assign(test_msg_.cpu_vint, 987); + assign(test_msg_.dev_vin, -9999); + assign(test_msg_.fe_temperature, 4776); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_device_monitor_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_device_monitor_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_piksi_MsgDeviceMonitor1, Test) { - uint8_t encoded_frame[] = { - 85, 181, 0, 95, 66, 10, 241, 216, 219, - 3, 254, 6, 24, 24, 168, 18, 169, 30, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_device_monitor_t test_msg{}; - test_msg.cpu_temperature = 6168; - test_msg.cpu_vaux = 1790; - test_msg.cpu_vint = 987; - test_msg.dev_vin = -9999; - test_msg.fe_temperature = 4776; - - EXPECT_EQ(send_message(16991, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 16991); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu_temperature, 6168) - << "incorrect value for last_msg_.cpu_temperature, expected 6168, is " - << last_msg_.cpu_temperature; - EXPECT_EQ(last_msg_.cpu_vaux, 1790) - << "incorrect value for last_msg_.cpu_vaux, expected 1790, is " - << last_msg_.cpu_vaux; - EXPECT_EQ(last_msg_.cpu_vint, 987) - << "incorrect value for last_msg_.cpu_vint, expected 987, is " - << last_msg_.cpu_vint; - EXPECT_EQ(last_msg_.dev_vin, -9999) - << "incorrect value for last_msg_.dev_vin, expected -9999, is " - << last_msg_.dev_vin; - EXPECT_EQ(last_msg_.fe_temperature, 4776) - << "incorrect value for last_msg_.fe_temperature, expected 4776, is " - << last_msg_.fe_temperature; -} -class Test_auto_check_sbp_piksi_MsgDeviceMonitor2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgDeviceMonitor2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_device_monitor_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDeviceMonitor, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDeviceMonitor); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->device_monitor, + sizeof(msg->device_monitor)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_device_monitor_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.device_monitor, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDeviceMonitor); + info.sender_id = 16991; + info.preamble = 0x55; + info.crc = 0x1ea9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_device_monitor_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_device_monitor_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_device_monitor_t &lesser, + const sbp_msg_device_monitor_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_device_monitor_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_device_monitor_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_device_monitor_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_device_monitor_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_piksi_MsgDeviceMonitor2, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_device_monitor_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { 85, 181, 0, 95, 66, 10, 241, 216, 219, - 3, 253, 6, 22, 24, 168, 18, 19, 114, + 3, 254, 6, 24, 24, 168, 18, 169, 30, + }; + uint8_t encoded_payload_[10] = { + 241, 216, 219, 3, 254, 6, 24, 24, 168, 18, }; +}; - sbp_msg_device_monitor_t test_msg{}; - test_msg.cpu_temperature = 6166; - test_msg.cpu_vaux = 1789; - test_msg.cpu_vint = 987; - test_msg.dev_vin = -9999; - test_msg.fe_temperature = 4776; - - EXPECT_EQ(send_message(16991, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 16991); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu_temperature, 6166) - << "incorrect value for last_msg_.cpu_temperature, expected 6166, is " - << last_msg_.cpu_temperature; - EXPECT_EQ(last_msg_.cpu_vaux, 1789) - << "incorrect value for last_msg_.cpu_vaux, expected 1789, is " - << last_msg_.cpu_vaux; - EXPECT_EQ(last_msg_.cpu_vint, 987) - << "incorrect value for last_msg_.cpu_vint, expected 987, is " - << last_msg_.cpu_vint; - EXPECT_EQ(last_msg_.dev_vin, -9999) - << "incorrect value for last_msg_.dev_vin, expected -9999, is " - << last_msg_.dev_vin; - EXPECT_EQ(last_msg_.fe_temperature, 4776) - << "incorrect value for last_msg_.fe_temperature, expected 4776, is " - << last_msg_.fe_temperature; -} -class Test_auto_check_sbp_piksi_MsgDeviceMonitor3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgDeviceMonitor3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_device_monitor_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgDeviceMonitor, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDeviceMonitor, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ( + sbp_msg_device_monitor_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_device_monitor_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_device_monitor_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_piksi_MsgDeviceMonitor3, Test) { - uint8_t encoded_frame[] = { - 85, 181, 0, 95, 66, 10, 241, 216, 218, - 3, 252, 6, 6, 24, 168, 18, 199, 107, - }; + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_device_monitor_t test_msg{}; - test_msg.cpu_temperature = 6150; - test_msg.cpu_vaux = 1788; - test_msg.cpu_vint = 986; - test_msg.dev_vin = -9999; - test_msg.fe_temperature = 4776; - - EXPECT_EQ(send_message(16991, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 16991); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu_temperature, 6150) - << "incorrect value for last_msg_.cpu_temperature, expected 6150, is " - << last_msg_.cpu_temperature; - EXPECT_EQ(last_msg_.cpu_vaux, 1788) - << "incorrect value for last_msg_.cpu_vaux, expected 1788, is " - << last_msg_.cpu_vaux; - EXPECT_EQ(last_msg_.cpu_vint, 986) - << "incorrect value for last_msg_.cpu_vint, expected 986, is " - << last_msg_.cpu_vint; - EXPECT_EQ(last_msg_.dev_vin, -9999) - << "incorrect value for last_msg_.dev_vin, expected -9999, is " - << last_msg_.dev_vin; - EXPECT_EQ(last_msg_.fe_temperature, 4776) - << "incorrect value for last_msg_.fe_temperature, expected 4776, is " - << last_msg_.fe_temperature; -} -class Test_auto_check_sbp_piksi_MsgDeviceMonitor4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgDeviceMonitor4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDeviceMonitor, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_device_monitor_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_device_monitor_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_piksi_MsgDeviceMonitor4, Test) { - uint8_t encoded_frame[] = { - 85, 181, 0, 95, 66, 10, 241, 216, 220, - 3, 253, 6, 235, 23, 168, 18, 241, 63, - }; +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_device_monitor_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - sbp_msg_device_monitor_t test_msg{}; - test_msg.cpu_temperature = 6123; - test_msg.cpu_vaux = 1789; - test_msg.cpu_vint = 988; - test_msg.dev_vin = -9999; - test_msg.fe_temperature = 4776; - - EXPECT_EQ(send_message(16991, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 16991); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu_temperature, 6123) - << "incorrect value for last_msg_.cpu_temperature, expected 6123, is " - << last_msg_.cpu_temperature; - EXPECT_EQ(last_msg_.cpu_vaux, 1789) - << "incorrect value for last_msg_.cpu_vaux, expected 1789, is " - << last_msg_.cpu_vaux; - EXPECT_EQ(last_msg_.cpu_vint, 988) - << "incorrect value for last_msg_.cpu_vint, expected 988, is " - << last_msg_.cpu_vint; - EXPECT_EQ(last_msg_.dev_vin, -9999) - << "incorrect value for last_msg_.dev_vin, expected -9999, is " - << last_msg_.dev_vin; - EXPECT_EQ(last_msg_.fe_temperature, 4776) - << "incorrect value for last_msg_.fe_temperature, expected 4776, is " - << last_msg_.fe_temperature; + EXPECT_EQ(sbp_message_send(&state, SbpMsgDeviceMonitor, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_temperature, greater.cpu_temperature); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vaux, greater.cpu_vaux); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vint, greater.cpu_vint); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.dev_vin, greater.dev_vin); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.fe_temperature, greater.fe_temperature); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDeviceMonitor); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DEVICE_MONITOR"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_device_monitor_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_device_monitor_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.device_monitor, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.device_monitor, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDeviceMonitor, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDeviceMonitor, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgDeviceMonitor2 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgDeviceMonitor2() { + assign(test_msg_.cpu_temperature, 6166); + assign(test_msg_.cpu_vaux, 1789); + assign(test_msg_.cpu_vint, 987); + assign(test_msg_.dev_vin, -9999); + assign(test_msg_.fe_temperature, 4776); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_device_monitor_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDeviceMonitor, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDeviceMonitor); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->device_monitor, + sizeof(msg->device_monitor)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_device_monitor_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.device_monitor, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDeviceMonitor); + info.sender_id = 16991; + info.preamble = 0x55; + info.crc = 0x7213; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_device_monitor_t &lesser, + const sbp_msg_device_monitor_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_device_monitor_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_device_monitor_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_device_monitor_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_device_monitor_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_device_monitor_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { + 85, 181, 0, 95, 66, 10, 241, 216, 219, + 3, 253, 6, 22, 24, 168, 18, 19, 114, + }; + uint8_t encoded_payload_[10] = { + 241, 216, 219, 3, 253, 6, 22, 24, 168, 18, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_device_monitor_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgDeviceMonitor, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDeviceMonitor, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ( + sbp_msg_device_monitor_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDeviceMonitor, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_device_monitor_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDeviceMonitor, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_temperature, greater.cpu_temperature); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vaux, greater.cpu_vaux); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vint, greater.cpu_vint); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.dev_vin, greater.dev_vin); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.fe_temperature, greater.fe_temperature); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDeviceMonitor); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DEVICE_MONITOR"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_device_monitor_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_device_monitor_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.device_monitor, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.device_monitor, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDeviceMonitor, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDeviceMonitor, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgDeviceMonitor3 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgDeviceMonitor3() { + assign(test_msg_.cpu_temperature, 6150); + assign(test_msg_.cpu_vaux, 1788); + assign(test_msg_.cpu_vint, 986); + assign(test_msg_.dev_vin, -9999); + assign(test_msg_.fe_temperature, 4776); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_device_monitor_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDeviceMonitor, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDeviceMonitor); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->device_monitor, + sizeof(msg->device_monitor)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_device_monitor_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.device_monitor, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDeviceMonitor); + info.sender_id = 16991; + info.preamble = 0x55; + info.crc = 0x6bc7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_device_monitor_t &lesser, + const sbp_msg_device_monitor_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_device_monitor_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_device_monitor_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_device_monitor_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_device_monitor_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_device_monitor_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { + 85, 181, 0, 95, 66, 10, 241, 216, 218, + 3, 252, 6, 6, 24, 168, 18, 199, 107, + }; + uint8_t encoded_payload_[10] = { + 241, 216, 218, 3, 252, 6, 6, 24, 168, 18, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_device_monitor_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgDeviceMonitor, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDeviceMonitor, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ( + sbp_msg_device_monitor_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDeviceMonitor, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_device_monitor_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDeviceMonitor, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_temperature, greater.cpu_temperature); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vaux, greater.cpu_vaux); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vint, greater.cpu_vint); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.dev_vin, greater.dev_vin); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.fe_temperature, greater.fe_temperature); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDeviceMonitor); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DEVICE_MONITOR"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_device_monitor_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_device_monitor_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.device_monitor, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.device_monitor, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDeviceMonitor, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDeviceMonitor, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgDeviceMonitor4 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgDeviceMonitor4() { + assign(test_msg_.cpu_temperature, 6123); + assign(test_msg_.cpu_vaux, 1789); + assign(test_msg_.cpu_vint, 988); + assign(test_msg_.dev_vin, -9999); + assign(test_msg_.fe_temperature, 4776); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_device_monitor_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDeviceMonitor, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_device_monitor_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDeviceMonitor); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->device_monitor, + sizeof(msg->device_monitor)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_device_monitor_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.device_monitor, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDeviceMonitor); + info.sender_id = 16991; + info.preamble = 0x55; + info.crc = 0x3ff1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_device_monitor_t &lesser, + const sbp_msg_device_monitor_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_device_monitor_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_device_monitor_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_device_monitor_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_device_monitor_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDeviceMonitor, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_device_monitor_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { + 85, 181, 0, 95, 66, 10, 241, 216, 220, + 3, 253, 6, 235, 23, 168, 18, 241, 63, + }; + uint8_t encoded_payload_[10] = { + 241, 216, 220, 3, 253, 6, 235, 23, 168, 18, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_device_monitor_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgDeviceMonitor, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDeviceMonitor, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + EXPECT_EQ(sbp_msg_device_monitor_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ( + sbp_msg_device_monitor_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDeviceMonitor, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_device_monitor_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_device_monitor_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDeviceMonitor, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_temperature, greater.cpu_temperature); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vaux, greater.cpu_vaux); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.cpu_vint, greater.cpu_vint); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.dev_vin, greater.dev_vin); + comparison_tests(lesser, greater); + } + { + sbp_msg_device_monitor_t lesser = info.test_msg; + sbp_msg_device_monitor_t greater = info.test_msg; + make_lesser_greater(lesser.fe_temperature, greater.fe_temperature); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDeviceMonitor); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DEVICE_MONITOR"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_device_monitor_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_device_monitor_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.device_monitor, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.device_monitor, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_device_monitor_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDeviceMonitor, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgDeviceMonitor4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDeviceMonitor, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgIarState.cc b/c/test/cpp/auto_check_sbp_piksi_MsgIarState.cc index ea30328dbb..a679a6b819 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgIarState.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgIarState.cc @@ -16,559 +16,3815 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgIarState0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgIarState0 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgIarState0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgIarState0() { assign(test_msg_.num_hyps, 1); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8cd8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_piksi_MsgIarState0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 25, 0, 246, 215, 4, 1, 0, 0, 0, 216, 140, }; + uint8_t encoded_payload_[4] = { + 1, + 0, + 0, + 0, + }; +}; - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 1; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 1) - << "incorrect value for last_msg_.num_hyps, expected 1, is " - << last_msg_.num_hyps; + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); } -class Test_auto_check_sbp_piksi_MsgIarState1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgIarState1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_piksi_MsgIarState1, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 0, 0, 0, 0, 18, 176, - }; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 0; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 0) - << "incorrect value for last_msg_.num_hyps, expected 0, is " - << last_msg_.num_hyps; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } -class Test_auto_check_sbp_piksi_MsgIarState2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgIarState2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} -TEST_F(Test_auto_check_sbp_piksi_MsgIarState2, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 1, 0, 0, 0, 166, 198, - }; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 1; +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 1) - << "incorrect value for last_msg_.num_hyps, expected 1, is " - << last_msg_.num_hyps; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } -class Test_auto_check_sbp_piksi_MsgIarState3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + +class Testauto_check_sbp_piksi_MsgIarState1 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgIarState3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgIarState1() { assign(test_msg_.num_hyps, 0); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xb012; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_piksi_MsgIarState3, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 217, 2, 0, 0, 6, 133, + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 0, 0, 0, 0, 18, 176, + }; + uint8_t encoded_payload_[4] = { + 0, + 0, + 0, + 0, }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 729; +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 729) - << "incorrect value for last_msg_.num_hyps, expected 729, is " - << last_msg_.num_hyps; +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); } -class Test_auto_check_sbp_piksi_MsgIarState4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgIarState4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_piksi_MsgIarState4, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 216, 2, 0, 0, 178, 243, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 728; +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 728) - << "incorrect value for last_msg_.num_hyps, expected 728, is " - << last_msg_.num_hyps; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } -class Test_auto_check_sbp_piksi_MsgIarState5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + +class Testauto_check_sbp_piksi_MsgIarState2 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgIarState5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgIarState2() { assign(test_msg_.num_hyps, 1); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xc6a6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_piksi_MsgIarState5, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 215, 2, 0, 0, 92, 39, + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 1, 0, 0, 0, 166, 198, + }; + uint8_t encoded_payload_[4] = { + 1, + 0, + 0, + 0, }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 727; +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 727) - << "incorrect value for last_msg_.num_hyps, expected 727, is " - << last_msg_.num_hyps; +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); } -class Test_auto_check_sbp_piksi_MsgIarState6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgIarState6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_iar_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_iar_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_piksi_MsgIarState6, Test) { - uint8_t encoded_frame[] = { - 85, 25, 0, 195, 4, 4, 211, 2, 0, 0, 173, 237, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_iar_state_t test_msg{}; - test_msg.num_hyps = 723; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.num_hyps, 723) - << "incorrect value for last_msg_.num_hyps, expected 723, is " - << last_msg_.num_hyps; +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); } + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgIarState3 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgIarState3() { assign(test_msg_.num_hyps, 729); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x8506; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 217, 2, 0, 0, 6, 133, + }; + uint8_t encoded_payload_[4] = { + 217, + 2, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgIarState4 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgIarState4() { assign(test_msg_.num_hyps, 728); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xf3b2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 216, 2, 0, 0, 178, 243, + }; + uint8_t encoded_payload_[4] = { + 216, + 2, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgIarState5 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgIarState5() { assign(test_msg_.num_hyps, 727); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x275c; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 215, 2, 0, 0, 92, 39, + }; + uint8_t encoded_payload_[4] = { + 215, + 2, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgIarState6 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgIarState6() { assign(test_msg_.num_hyps, 723); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_iar_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgIarState, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_iar_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgIarState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->iar_state, sizeof(msg->iar_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_iar_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.iar_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgIarState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xedad; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_iar_state_t &lesser, + const sbp_msg_iar_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_iar_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_iar_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_iar_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_iar_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgIarState, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgIarState, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_iar_state_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { + 85, 25, 0, 195, 4, 4, 211, 2, 0, 0, 173, 237, + }; + uint8_t encoded_payload_[4] = { + 211, + 2, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_iar_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgIarState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgIarState, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_iar_state_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_iar_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgIarState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + EXPECT_EQ(sbp_msg_iar_state_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_iar_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_iar_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgIarState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_iar_state_t lesser = info.test_msg; + sbp_msg_iar_state_t greater = info.test_msg; + make_lesser_greater(lesser.num_hyps, greater.num_hyps); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgIarState); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_IAR_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_iar_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_iar_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.iar_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.iar_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_iar_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgIarState, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgIarState6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgIarState, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgNetworkBandwidthUsage.cc b/c/test/cpp/auto_check_sbp_piksi_MsgNetworkBandwidthUsage.cc index 3a2fe789ef..f04a9e647b 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgNetworkBandwidthUsage.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgNetworkBandwidthUsage.cc @@ -16,66 +16,345 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgNetworkBandwidthUsage0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0 + : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgNetworkBandwidthUsage0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0() { + assign(test_msg_.interfaces[0].duration, 2159176030); + { + const char assign_string[] = {(char)99, (char)97, (char)110, (char)48, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.interfaces[0].interface_name, assign_string, + sizeof(assign_string)); + } + assign(test_msg_.interfaces[0].rx_bytes, 0); + assign(test_msg_.interfaces[0].total_bytes, 0); + assign(test_msg_.interfaces[0].tx_bytes, 0); + + assign(test_msg_.interfaces[1].duration, 2159176030); + { + const char assign_string[] = {(char)99, (char)97, (char)110, (char)49, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.interfaces[1].interface_name, assign_string, + sizeof(assign_string)); + } + assign(test_msg_.interfaces[1].rx_bytes, 0); + assign(test_msg_.interfaces[1].total_bytes, 0); + assign(test_msg_.interfaces[1].tx_bytes, 0); + + assign(test_msg_.interfaces[2].duration, 2159176030); + { + const char assign_string[] = {(char)101, (char)116, (char)104, (char)48, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.interfaces[2].interface_name, assign_string, + sizeof(assign_string)); + } + assign(test_msg_.interfaces[2].rx_bytes, 4036234989); + assign(test_msg_.interfaces[2].total_bytes, 3411995557); + assign(test_msg_.interfaces[2].tx_bytes, 3670727864); + + assign(test_msg_.interfaces[3].duration, 2159176030); + { + const char assign_string[] = {(char)108, (char)111, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.interfaces[3].interface_name, assign_string, + sizeof(assign_string)); + } + assign(test_msg_.interfaces[3].rx_bytes, 0); + assign(test_msg_.interfaces[3].total_bytes, 0); + assign(test_msg_.interfaces[3].tx_bytes, 0); + + assign(test_msg_.interfaces[4].duration, 2159176030); + { + const char assign_string[] = {(char)115, (char)105, (char)116, (char)48, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.interfaces[4].interface_name, assign_string, + sizeof(assign_string)); + } + assign(test_msg_.interfaces[4].rx_bytes, 0); + assign(test_msg_.interfaces[4].total_bytes, 0); + assign(test_msg_.interfaces[4].tx_bytes, 0); + assign(test_msg_.n_interfaces, 5); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_network_bandwidth_usage_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_network_bandwidth_usage_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_network_bandwidth_usage_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgNetworkBandwidthUsage, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_network_bandwidth_usage_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgNetworkBandwidthUsage); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->network_bandwidth_usage, + sizeof(msg->network_bandwidth_usage)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_network_bandwidth_usage_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.network_bandwidth_usage, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgNetworkBandwidthUsage); + info.sender_id = 31183; + info.preamble = 0x55; + info.crc = 0x851B; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 200; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_network_bandwidth_usage_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_network_bandwidth_usage_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_network_bandwidth_usage_t &lesser, + const sbp_msg_network_bandwidth_usage_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_network_bandwidth_usage_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_network_bandwidth_usage_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_network_bandwidth_usage_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgNetworkBandwidthUsage, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgNetworkBandwidthUsage, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgNetworkBandwidthUsage, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgNetworkBandwidthUsage, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); -TEST_F(Test_auto_check_sbp_piksi_MsgNetworkBandwidthUsage0, Test) { - uint8_t encoded_frame[] = { + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_network_bandwidth_usage_t test_msg_{}; + uint8_t encoded_frame_[200 + 8] = { 85, 189, 0, 207, 121, 200, 94, 105, 178, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 97, 110, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -91,225 +370,526 @@ TEST_F(Test_auto_check_sbp_piksi_MsgNetworkBandwidthUsage0, Test) { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 115, 105, 116, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 133, }; + uint8_t encoded_payload_[200] = { + 94, 105, 178, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 99, 97, 110, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 94, 105, 178, 128, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 99, 97, 110, 49, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 94, 105, 178, 128, 0, 0, 0, 0, 165, 235, 94, 203, 0, 0, 0, 0, + 237, 14, 148, 240, 184, 220, 202, 218, 101, 116, 104, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 94, 105, 178, 128, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 108, 111, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 94, 105, 178, 128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 115, 105, 116, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + }; +}; - sbp_msg_network_bandwidth_usage_t test_msg{}; +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_network_bandwidth_usage_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgNetworkBandwidthUsage, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[200]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 200); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 200), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgNetworkBandwidthUsage, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 200); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 200), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[200]; + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 200), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[200]; + + for (uint8_t i = 0; i < 200; i++) { + EXPECT_EQ(sbp_msg_network_bandwidth_usage_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_network_bandwidth_usage_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 200); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgNetworkBandwidthUsage, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 200); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_network_bandwidth_usage_t msg{}; + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_network_bandwidth_usage_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_network_bandwidth_usage_t t{}; + return sbp_msg_network_bandwidth_usage_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_network_bandwidth_usage_t t{}; + t.n_interfaces = 1; + return sbp_msg_network_bandwidth_usage_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_network_bandwidth_usage_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.interfaces[0].duration = 2159176030; +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgNetworkBandwidthUsage, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[0].duration, + greater.interfaces[0].duration); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[0].interface_name, + greater.interfaces[0].interface_name); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[0].rx_bytes, + greater.interfaces[0].rx_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[0].total_bytes, + greater.interfaces[0].total_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[0].tx_bytes, + greater.interfaces[0].tx_bytes); + comparison_tests(lesser, greater); + } + + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[1].duration, + greater.interfaces[1].duration); + comparison_tests(lesser, greater); + } { - const char assign_string[] = {(char)99, (char)97, (char)110, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.interfaces[0].interface_name, assign_string, - sizeof(assign_string)); - } - test_msg.interfaces[0].rx_bytes = 0; - test_msg.interfaces[0].total_bytes = 0; - test_msg.interfaces[0].tx_bytes = 0; - - test_msg.interfaces[1].duration = 2159176030; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[1].interface_name, + greater.interfaces[1].interface_name); + comparison_tests(lesser, greater); + } { - const char assign_string[] = {(char)99, (char)97, (char)110, (char)49, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.interfaces[1].interface_name, assign_string, - sizeof(assign_string)); - } - test_msg.interfaces[1].rx_bytes = 0; - test_msg.interfaces[1].total_bytes = 0; - test_msg.interfaces[1].tx_bytes = 0; - - test_msg.interfaces[2].duration = 2159176030; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[1].rx_bytes, + greater.interfaces[1].rx_bytes); + comparison_tests(lesser, greater); + } { - const char assign_string[] = {(char)101, (char)116, (char)104, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.interfaces[2].interface_name, assign_string, - sizeof(assign_string)); - } - test_msg.interfaces[2].rx_bytes = 4036234989; - test_msg.interfaces[2].total_bytes = 3411995557; - test_msg.interfaces[2].tx_bytes = 3670727864; - - test_msg.interfaces[3].duration = 2159176030; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[1].total_bytes, + greater.interfaces[1].total_bytes); + comparison_tests(lesser, greater); + } { - const char assign_string[] = {(char)108, (char)111, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.interfaces[3].interface_name, assign_string, - sizeof(assign_string)); - } - test_msg.interfaces[3].rx_bytes = 0; - test_msg.interfaces[3].total_bytes = 0; - test_msg.interfaces[3].tx_bytes = 0; - - test_msg.interfaces[4].duration = 2159176030; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[1].tx_bytes, + greater.interfaces[1].tx_bytes); + comparison_tests(lesser, greater); + } + { - const char assign_string[] = {(char)115, (char)105, (char)116, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.interfaces[4].interface_name, assign_string, - sizeof(assign_string)); - } - test_msg.interfaces[4].rx_bytes = 0; - test_msg.interfaces[4].total_bytes = 0; - test_msg.interfaces[4].tx_bytes = 0; - test_msg.n_interfaces = 5; - - EXPECT_EQ(send_message(31183, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 31183); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.interfaces[0].duration, 2159176030) - << "incorrect value for last_msg_.interfaces[0].duration, expected " - "2159176030, is " - << last_msg_.interfaces[0].duration; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[2].duration, + greater.interfaces[2].duration); + comparison_tests(lesser, greater); + } { - const char check_string[] = {(char)99, (char)97, (char)110, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.interfaces[0].interface_name, check_string, - sizeof(check_string)), - 0) - << "incorrect value for last_msg_.interfaces[0].interface_name, " - "expected string '" - << check_string << "', is '" << last_msg_.interfaces[0].interface_name - << "'"; - } - EXPECT_EQ(last_msg_.interfaces[0].rx_bytes, 0) - << "incorrect value for last_msg_.interfaces[0].rx_bytes, expected 0, is " - << last_msg_.interfaces[0].rx_bytes; - EXPECT_EQ(last_msg_.interfaces[0].total_bytes, 0) - << "incorrect value for last_msg_.interfaces[0].total_bytes, expected 0, " - "is " - << last_msg_.interfaces[0].total_bytes; - EXPECT_EQ(last_msg_.interfaces[0].tx_bytes, 0) - << "incorrect value for last_msg_.interfaces[0].tx_bytes, expected 0, is " - << last_msg_.interfaces[0].tx_bytes; - EXPECT_EQ(last_msg_.interfaces[1].duration, 2159176030) - << "incorrect value for last_msg_.interfaces[1].duration, expected " - "2159176030, is " - << last_msg_.interfaces[1].duration; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[2].interface_name, + greater.interfaces[2].interface_name); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[2].rx_bytes, + greater.interfaces[2].rx_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[2].total_bytes, + greater.interfaces[2].total_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[2].tx_bytes, + greater.interfaces[2].tx_bytes); + comparison_tests(lesser, greater); + } + + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[3].duration, + greater.interfaces[3].duration); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[3].interface_name, + greater.interfaces[3].interface_name); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[3].rx_bytes, + greater.interfaces[3].rx_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[3].total_bytes, + greater.interfaces[3].total_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[3].tx_bytes, + greater.interfaces[3].tx_bytes); + comparison_tests(lesser, greater); + } + + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[4].duration, + greater.interfaces[4].duration); + comparison_tests(lesser, greater); + } + { + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[4].interface_name, + greater.interfaces[4].interface_name); + comparison_tests(lesser, greater); + } { - const char check_string[] = {(char)99, (char)97, (char)110, (char)49, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.interfaces[1].interface_name, check_string, - sizeof(check_string)), - 0) - << "incorrect value for last_msg_.interfaces[1].interface_name, " - "expected string '" - << check_string << "', is '" << last_msg_.interfaces[1].interface_name - << "'"; - } - EXPECT_EQ(last_msg_.interfaces[1].rx_bytes, 0) - << "incorrect value for last_msg_.interfaces[1].rx_bytes, expected 0, is " - << last_msg_.interfaces[1].rx_bytes; - EXPECT_EQ(last_msg_.interfaces[1].total_bytes, 0) - << "incorrect value for last_msg_.interfaces[1].total_bytes, expected 0, " - "is " - << last_msg_.interfaces[1].total_bytes; - EXPECT_EQ(last_msg_.interfaces[1].tx_bytes, 0) - << "incorrect value for last_msg_.interfaces[1].tx_bytes, expected 0, is " - << last_msg_.interfaces[1].tx_bytes; - EXPECT_EQ(last_msg_.interfaces[2].duration, 2159176030) - << "incorrect value for last_msg_.interfaces[2].duration, expected " - "2159176030, is " - << last_msg_.interfaces[2].duration; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[4].rx_bytes, + greater.interfaces[4].rx_bytes); + comparison_tests(lesser, greater); + } { - const char check_string[] = {(char)101, (char)116, (char)104, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.interfaces[2].interface_name, check_string, - sizeof(check_string)), - 0) - << "incorrect value for last_msg_.interfaces[2].interface_name, " - "expected string '" - << check_string << "', is '" << last_msg_.interfaces[2].interface_name - << "'"; - } - EXPECT_EQ(last_msg_.interfaces[2].rx_bytes, 4036234989) - << "incorrect value for last_msg_.interfaces[2].rx_bytes, expected " - "4036234989, is " - << last_msg_.interfaces[2].rx_bytes; - EXPECT_EQ(last_msg_.interfaces[2].total_bytes, 3411995557) - << "incorrect value for last_msg_.interfaces[2].total_bytes, expected " - "3411995557, is " - << last_msg_.interfaces[2].total_bytes; - EXPECT_EQ(last_msg_.interfaces[2].tx_bytes, 3670727864) - << "incorrect value for last_msg_.interfaces[2].tx_bytes, expected " - "3670727864, is " - << last_msg_.interfaces[2].tx_bytes; - EXPECT_EQ(last_msg_.interfaces[3].duration, 2159176030) - << "incorrect value for last_msg_.interfaces[3].duration, expected " - "2159176030, is " - << last_msg_.interfaces[3].duration; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[4].total_bytes, + greater.interfaces[4].total_bytes); + comparison_tests(lesser, greater); + } { - const char check_string[] = {(char)108, (char)111, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.interfaces[3].interface_name, check_string, - sizeof(check_string)), - 0) - << "incorrect value for last_msg_.interfaces[3].interface_name, " - "expected string '" - << check_string << "', is '" << last_msg_.interfaces[3].interface_name - << "'"; - } - EXPECT_EQ(last_msg_.interfaces[3].rx_bytes, 0) - << "incorrect value for last_msg_.interfaces[3].rx_bytes, expected 0, is " - << last_msg_.interfaces[3].rx_bytes; - EXPECT_EQ(last_msg_.interfaces[3].total_bytes, 0) - << "incorrect value for last_msg_.interfaces[3].total_bytes, expected 0, " - "is " - << last_msg_.interfaces[3].total_bytes; - EXPECT_EQ(last_msg_.interfaces[3].tx_bytes, 0) - << "incorrect value for last_msg_.interfaces[3].tx_bytes, expected 0, is " - << last_msg_.interfaces[3].tx_bytes; - EXPECT_EQ(last_msg_.interfaces[4].duration, 2159176030) - << "incorrect value for last_msg_.interfaces[4].duration, expected " - "2159176030, is " - << last_msg_.interfaces[4].duration; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.interfaces[4].tx_bytes, + greater.interfaces[4].tx_bytes); + comparison_tests(lesser, greater); + } { - const char check_string[] = {(char)115, (char)105, (char)116, (char)48, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.interfaces[4].interface_name, check_string, - sizeof(check_string)), - 0) - << "incorrect value for last_msg_.interfaces[4].interface_name, " - "expected string '" - << check_string << "', is '" << last_msg_.interfaces[4].interface_name - << "'"; - } - EXPECT_EQ(last_msg_.interfaces[4].rx_bytes, 0) - << "incorrect value for last_msg_.interfaces[4].rx_bytes, expected 0, is " - << last_msg_.interfaces[4].rx_bytes; - EXPECT_EQ(last_msg_.interfaces[4].total_bytes, 0) - << "incorrect value for last_msg_.interfaces[4].total_bytes, expected 0, " - "is " - << last_msg_.interfaces[4].total_bytes; - EXPECT_EQ(last_msg_.interfaces[4].tx_bytes, 0) - << "incorrect value for last_msg_.interfaces[4].tx_bytes, expected 0, is " - << last_msg_.interfaces[4].tx_bytes; - EXPECT_EQ(last_msg_.n_interfaces, 5) - << "incorrect value for last_msg_.n_interfaces, expected 5, is " - << last_msg_.n_interfaces; + sbp_msg_network_bandwidth_usage_t lesser = info.test_msg; + sbp_msg_network_bandwidth_usage_t greater = info.test_msg; + make_lesser_greater(lesser.n_interfaces, greater.n_interfaces); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgNetworkBandwidthUsage); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_NETWORK_BANDWIDTH_USAGE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_network_bandwidth_usage_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_network_bandwidth_usage_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.network_bandwidth_usage, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.network_bandwidth_usage, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[200]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 200); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 200), 0); } + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_network_bandwidth_usage_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 200); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgNetworkBandwidthUsage, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgNetworkBandwidthUsage0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgNetworkBandwidthUsage, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgThreadState.cc b/c/test/cpp/auto_check_sbp_piksi_MsgThreadState.cc index d73b9c2ea8..2c6541471b 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgThreadState.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgThreadState.cc @@ -16,1104 +16,6322 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgThreadState0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgThreadState0 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgThreadState0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgThreadState0() { + assign(test_msg_.cpu, 0); + { + const char assign_string[] = { + (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 2460); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState0, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 246, 215, 26, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 9, 0, 0, 73, 138, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 0; - { - const char assign_string[] = { - (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); - } - test_msg.stack_free = 2460; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + uint32_t remaining() const noexcept { return max_len_ - offset_; } - while (dummy_rd_ < dummy_wr_) { - process(); - } + const uint8_t *data() const noexcept { return buf_; } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 0) - << "incorrect value for last_msg_.cpu, expected 0, is " << last_msg_.cpu; - { - const char check_string[] = { - (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 2460) - << "incorrect value for last_msg_.stack_free, expected 2460, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + uint32_t len() const noexcept { return offset_; } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState1, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 246, 215, 26, 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 2, 36, 0, 0, 0, 151, 20, + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 595; - { - const char assign_string[] = { - (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); - } - test_msg.stack_free = 36; + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + std::vector outputs{}; - while (dummy_rd_ < dummy_wr_) { - process(); - } + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 595) - << "incorrect value for last_msg_.cpu, expected 595, is " - << last_msg_.cpu; - { - const char check_string[] = { - (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 36) - << "incorrect value for last_msg_.stack_free, expected 36, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState2, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 246, 215, 26, 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 116, 4, 0, 0, 226, 60, + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 14; - { - const char assign_string[] = { - (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); - } - test_msg.stack_free = 1140; + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; - while (dummy_rd_ < dummy_wr_) { - process(); - } + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x8a49; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 14) - << "incorrect value for last_msg_.cpu, expected 14, is " << last_msg_.cpu; - { - const char check_string[] = { - (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 1140) - << "incorrect value for last_msg_.stack_free, expected 1140, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState3, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 246, 215, 26, 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 196, 19, 0, 0, 90, 169, - }; + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 1; - { - const char assign_string[] = { - (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - test_msg.stack_free = 5060; - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } - while (dummy_rd_ < dummy_wr_) { - process(); + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 1) - << "incorrect value for last_msg_.cpu, expected 1, is " << last_msg_.cpu; - { - const char check_string[] = { - (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 5060) - << "incorrect value for last_msg_.stack_free, expected 5060, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 246, 215, 26, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 9, 0, 0, 73, 138, + }; + uint8_t encoded_payload_[26] = { + 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 156, 9, 0, 0, + }; }; -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState4, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 246, 215, 26, 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 20, 9, 0, 0, 47, 75, - }; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 7; - { - const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)97, - (char)99, (char)113, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } - test_msg.stack_free = 2324; +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 7) - << "incorrect value for last_msg_.cpu, expected 7, is " << last_msg_.cpu; - { - const char check_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)97, - (char)99, (char)113, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 2324) - << "incorrect value for last_msg_.stack_free, expected 2324, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState5, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 9, 0, 0, 195, 212, - }; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 0; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } { - const char assign_string[] = { - (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); } - test_msg.stack_free = 2452; +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 0) - << "incorrect value for last_msg_.cpu, expected 0, is " << last_msg_.cpu; - { - const char check_string[] = { - (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 2452) - << "incorrect value for last_msg_.stack_free, expected 2452, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState6 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState1 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgThreadState6() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgThreadState1() { + assign(test_msg_.cpu, 595); + { + const char assign_string[] = { + (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 36); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState6, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 1, 36, 0, 0, 0, 225, 18, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 484; - { - const char assign_string[] = { - (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); - } - test_msg.stack_free = 36; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + uint32_t remaining() const noexcept { return max_len_ - offset_; } - while (dummy_rd_ < dummy_wr_) { - process(); - } + const uint8_t *data() const noexcept { return buf_; } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 484) - << "incorrect value for last_msg_.cpu, expected 484, is " - << last_msg_.cpu; - { - const char check_string[] = { - (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 36) - << "incorrect value for last_msg_.stack_free, expected 36, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState7 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState7() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + uint32_t len() const noexcept { return offset_; } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState7, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 1, 92, 7, 0, 0, 166, 116, + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 394; - { - const char assign_string[] = { - (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); - } - test_msg.stack_free = 1884; + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + std::vector outputs{}; - while (dummy_rd_ < dummy_wr_) { - process(); - } + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 394) - << "incorrect value for last_msg_.cpu, expected 394, is " - << last_msg_.cpu; - { - const char check_string[] = { - (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 1884) - << "incorrect value for last_msg_.stack_free, expected 1884, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState8 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState8() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x1497; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState8, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 12, 0, 0, 229, 174, - }; + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 1; - { - const char assign_string[] = { - (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - test_msg.stack_free = 3076; - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } - while (dummy_rd_ < dummy_wr_) { - process(); + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 1) - << "incorrect value for last_msg_.cpu, expected 1, is " << last_msg_.cpu; - { - const char check_string[] = { - (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 3076) - << "incorrect value for last_msg_.stack_free, expected 3076, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState9 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState9() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 246, 215, 26, 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 83, 2, 36, 0, 0, 0, 151, 20, + }; + uint8_t encoded_payload_[26] = { + 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 83, 2, 36, 0, 0, 0, + }; }; -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState9, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 124, 9, 0, 0, 52, 2, - }; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 10; - { - const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)97, - (char)99, (char)113, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } - test_msg.stack_free = 2428; +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 10) - << "incorrect value for last_msg_.cpu, expected 10, is " << last_msg_.cpu; - { - const char check_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)97, - (char)99, (char)113, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 2428) - << "incorrect value for last_msg_.stack_free, expected 2428, is " - << last_msg_.stack_free; -} -class Test_auto_check_sbp_piksi_MsgThreadState10 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgThreadState10() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_thread_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_thread_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_piksi_MsgThreadState10, Test) { - uint8_t encoded_frame[] = { - 85, 23, 0, 195, 4, 26, 109, 97, 110, 97, 103, 101, 32, 116, 114, 97, 99, - 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 122, 54, - }; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_thread_state_t test_msg{}; - test_msg.cpu = 0; +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } { - const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)116, - (char)114, (char)97, (char)99, (char)107, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - memcpy(test_msg.name, assign_string, sizeof(assign_string)); + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); } - test_msg.stack_free = 2332; +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - while (dummy_rd_ < dummy_wr_) { - process(); - } + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cpu, 0) - << "incorrect value for last_msg_.cpu, expected 0, is " << last_msg_.cpu; - { - const char check_string[] = {(char)109, (char)97, (char)110, (char)97, - (char)103, (char)101, (char)32, (char)116, - (char)114, (char)97, (char)99, (char)107, - (char)0, (char)0, (char)0, (char)0, - (char)0, (char)0, (char)0, (char)0}; - EXPECT_EQ(memcmp(last_msg_.name, check_string, sizeof(check_string)), 0) - << "incorrect value for last_msg_.name, expected string '" - << check_string << "', is '" << last_msg_.name << "'"; - } - EXPECT_EQ(last_msg_.stack_free, 2332) - << "incorrect value for last_msg_.stack_free, expected 2332, is " - << last_msg_.stack_free; + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); } + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState2 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState2() { + assign(test_msg_.cpu, 14); + { + const char assign_string[] = { + (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 1140); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x3ce2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 246, 215, 26, 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 116, 4, 0, 0, 226, 60, + }; + uint8_t encoded_payload_[26] = { + 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 14, 0, 116, 4, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState3 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState3() { + assign(test_msg_.cpu, 1); + { + const char assign_string[] = { + (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 5060); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xa95a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 246, 215, 26, 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 196, 19, 0, 0, 90, 169, + }; + uint8_t encoded_payload_[26] = { + 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 196, 19, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState4 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState4() { + assign(test_msg_.cpu, 7); + { + const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, + (char)103, (char)101, (char)32, (char)97, + (char)99, (char)113, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 2324); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x4b2f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 246, 215, 26, 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 20, 9, 0, 0, 47, 75, + }; + uint8_t encoded_payload_[26] = { + 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 7, 0, 20, 9, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState5 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState5() { + assign(test_msg_.cpu, 0); + { + const char assign_string[] = { + (char)109, (char)97, (char)105, (char)110, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 2452); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xd4c3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 9, 0, 0, 195, 212, + }; + uint8_t encoded_payload_[26] = { + 109, 97, 105, 110, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 9, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState6 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState6() { + assign(test_msg_.cpu, 484); + { + const char assign_string[] = { + (char)105, (char)100, (char)108, (char)101, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 36); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x12e1; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 228, 1, 36, 0, 0, 0, 225, 18, + }; + uint8_t encoded_payload_[26] = { + 105, 100, 108, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 228, 1, 36, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState6, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState7 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState7() { + assign(test_msg_.cpu, 394); + { + const char assign_string[] = { + (char)78, (char)65, (char)80, (char)32, (char)73, (char)83, (char)82, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 1884); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x74a6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 138, 1, 92, 7, 0, 0, 166, 116, + }; + uint8_t encoded_payload_[26] = { + 78, 65, 80, 32, 73, 83, 82, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 138, 1, 92, 7, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState7, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState8 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState8() { + assign(test_msg_.cpu, 1); + { + const char assign_string[] = { + (char)83, (char)66, (char)80, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 3076); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xaee5; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 12, 0, 0, 229, 174, + }; + uint8_t encoded_payload_[26] = { + 83, 66, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 1, 0, 4, 12, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState8, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState9 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState9() { + assign(test_msg_.cpu, 10); + { + const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, + (char)103, (char)101, (char)32, (char)97, + (char)99, (char)113, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 2428); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x234; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 124, 9, 0, 0, 52, 2, + }; + uint8_t encoded_payload_[26] = { + 109, 97, 110, 97, 103, 101, 32, 97, 99, 113, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 10, 0, 124, 9, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState9, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgThreadState10 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgThreadState10() { + assign(test_msg_.cpu, 0); + { + const char assign_string[] = {(char)109, (char)97, (char)110, (char)97, + (char)103, (char)101, (char)32, (char)116, + (char)114, (char)97, (char)99, (char)107, + (char)0, (char)0, (char)0, (char)0, + (char)0, (char)0, (char)0, (char)0}; + memcpy(test_msg_.name, assign_string, sizeof(assign_string)); + } + assign(test_msg_.stack_free, 2332); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_thread_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgThreadState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_thread_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgThreadState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->thread_state, + sizeof(msg->thread_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_thread_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.thread_state, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgThreadState); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x367a; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 26; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_thread_state_t &lesser, + const sbp_msg_thread_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_thread_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_thread_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_thread_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_thread_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgThreadState, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgThreadState, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_thread_state_t test_msg_{}; + uint8_t encoded_frame_[26 + 8] = { + 85, 23, 0, 195, 4, 26, 109, 97, 110, 97, 103, 101, 32, 116, 114, 97, 99, + 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, 122, 54, + }; + uint8_t encoded_payload_[26] = { + 109, 97, 110, 97, 103, 101, 32, 116, 114, 97, 99, 107, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 9, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_thread_state_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgThreadState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgThreadState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + + for (uint8_t i = 0; i < 26; i++) { + EXPECT_EQ(sbp_msg_thread_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgThreadState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + EXPECT_EQ(sbp_msg_thread_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_thread_state_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_thread_state_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgThreadState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.cpu, greater.cpu); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.name, greater.name); + comparison_tests(lesser, greater); + } + { + sbp_msg_thread_state_t lesser = info.test_msg; + sbp_msg_thread_state_t greater = info.test_msg; + make_lesser_greater(lesser.stack_free, greater.stack_free); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgThreadState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_THREAD_STATE"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_thread_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_thread_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.thread_state, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.thread_state, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[26]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 26); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 26), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_thread_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 26); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgThreadState, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgThreadState10, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgThreadState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgUartState.cc b/c/test/cpp/auto_check_sbp_piksi_MsgUartState.cc index b5e7f666b1..2ddda17748 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgUartState.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgUartState.cc @@ -16,364 +16,1472 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgUartState0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgUartState0 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgUartState0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgUartState0() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 24); + assign(test_msg_.uart_a.tx_throughput, 0.8661972284317017); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 40); + assign(test_msg_.uart_b.tx_throughput, 2.9718310832977295); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 1); + assign(test_msg_.uart_ftdi.rx_throughput, 0.035211268812417984); + assign(test_msg_.uart_ftdi.tx_buffer_level, 81); + assign(test_msg_.uart_ftdi.tx_throughput, 5.063380241394043); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x7c47; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); -TEST_F(Test_auto_check_sbp_piksi_MsgUartState0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { 85, 24, 0, 246, 215, 58, 26, 191, 93, 63, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 123, 50, 62, 64, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 54, 7, 162, 64, 177, 57, 16, 61, 0, 0, 0, 0, 81, 1, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 71, 124, }; + uint8_t encoded_payload_[58] = { + 26, 191, 93, 63, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 123, + 50, 62, 64, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 54, 7, + 162, 64, 177, 57, 16, 61, 0, 0, 0, 0, 81, 1, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 24; - test_msg.uart_a.tx_throughput = 0.8661972284317017; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 40; - test_msg.uart_b.tx_throughput = 2.9718310832977295; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 1; - test_msg.uart_ftdi.rx_throughput = 0.035211268812417984; - test_msg.uart_ftdi.tx_buffer_level = 81; - test_msg.uart_ftdi.tx_throughput = 5.063380241394043; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 24) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 24, " - "is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.866197228432 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected " - "0.866197228432, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 40) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 40, " - "is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 2.9718310833 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected " - "2.9718310833, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 1) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 1, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0352112688124 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected " - "0.0352112688124, is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 81) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "81, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 5.06338024139 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "5.06338024139, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartState1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartState1 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgUartState1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgUartState1() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 24); + assign(test_msg_.uart_a.tx_throughput, 0.8746479153633118); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 40); + assign(test_msg_.uart_b.tx_throughput, 2.995774745941162); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 1); + assign(test_msg_.uart_ftdi.rx_throughput, 0.35211268067359924); + assign(test_msg_.uart_ftdi.tx_buffer_level, 85); + assign(test_msg_.uart_ftdi.tx_throughput, 6.7901411056518555); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xf899; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); -TEST_F(Test_auto_check_sbp_piksi_MsgUartState1, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { 85, 24, 0, 246, 215, 58, 237, 232, 95, 63, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 198, 186, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 214, 72, 217, 64, 29, 72, 180, 62, 0, 0, 0, 0, 85, 1, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 153, 248, }; + uint8_t encoded_payload_[58] = { + 237, 232, 95, 63, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 198, + 186, 63, 64, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 214, 72, + 217, 64, 29, 72, 180, 62, 0, 0, 0, 0, 85, 1, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 24; - test_msg.uart_a.tx_throughput = 0.8746479153633118; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 40; - test_msg.uart_b.tx_throughput = 2.995774745941162; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 1; - test_msg.uart_ftdi.rx_throughput = 0.35211268067359924; - test_msg.uart_ftdi.tx_buffer_level = 85; - test_msg.uart_ftdi.tx_throughput = 6.7901411056518555; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 24) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 24, " - "is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.874647915363 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected " - "0.874647915363, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 40) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 40, " - "is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 2.99577474594 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected " - "2.99577474594, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 1) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 1, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.352112680674 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected " - "0.352112680674, is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 85) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "85, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 6.79014110565 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "6.79014110565, is " - << last_msg_.uart_ftdi.tx_throughput; + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); } + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartState1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_piksi_MsgUartStateDepA.cc b/c/test/cpp/auto_check_sbp_piksi_MsgUartStateDepA.cc index 141b2283dd..5b92a06aee 100644 --- a/c/test/cpp/auto_check_sbp_piksi_MsgUartStateDepA.cc +++ b/c/test/cpp/auto_check_sbp_piksi_MsgUartStateDepA.cc @@ -16,1053 +16,4396 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_piksi_MsgUartStateDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_piksi_MsgUartStateDepA0 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgUartStateDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgUartStateDepA0() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 0); + assign(test_msg_.uart_a.tx_throughput, 0.0); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 0); + assign(test_msg_.uart_b.tx_throughput, 0.0); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 15); + assign(test_msg_.uart_ftdi.tx_throughput, 11.600000381469727); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x5f7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, 57, 65, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 247, 5, }; + uint8_t encoded_payload_[58] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 154, 153, + 57, 65, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 0; - test_msg.uart_a.tx_throughput = 0.0; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 0; - test_msg.uart_b.tx_throughput = 0.0; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 15; - test_msg.uart_ftdi.tx_throughput = 11.600000381469727; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 0, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected 0.0, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 0, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected 0.0, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 15) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "15, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 11.6000003815 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "11.6000003815, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartStateDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgUartStateDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA1, Test) { - uint8_t encoded_frame[] = { - 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 2, 43, 135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 65, 110, - }; + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 0; - test_msg.uart_a.tx_throughput = 0.0; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 0; - test_msg.uart_b.tx_throughput = 0.0; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 0; - test_msg.uart_ftdi.tx_throughput = 0.06599999964237213; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 0, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected 0.0, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 0, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected 0.0, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 0.0659999996424 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "0.0659999996424, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartStateDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartStateDepA1 : public ::testing::Test { public: - Test_auto_check_sbp_piksi_MsgUartStateDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_piksi_MsgUartStateDepA1() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 0); + assign(test_msg_.uart_a.tx_throughput, 0.0); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 0); + assign(test_msg_.uart_b.tx_throughput, 0.0); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 0); + assign(test_msg_.uart_ftdi.tx_throughput, 0.06599999964237213); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 4, 86, 14, 62, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 255, 255, 255, - 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 198, 36, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 0; - test_msg.uart_a.tx_throughput = 0.0; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 0; - test_msg.uart_b.tx_throughput = 0.0; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 10; - test_msg.uart_ftdi.tx_throughput = 0.13899999856948853; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 0, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected 0.0, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 0, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected 0.0, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 10) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "10, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 0.138999998569 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "0.138999998569, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartStateDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgUartStateDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6e41; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA3, Test) { - uint8_t encoded_frame[] = { + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 43, 135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 65, 110, }; + uint8_t encoded_payload_[58] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 43, + 135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 0; - test_msg.uart_a.tx_throughput = 0.0; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 0; - test_msg.uart_b.tx_throughput = 0.0; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 0; - test_msg.uart_ftdi.tx_throughput = 0.06599999964237213; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 0, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected 0.0, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 0, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected 0.0, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 0.0659999996424 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "0.0659999996424, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartStateDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgUartStateDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 138, 75, 6, 60, - 0, 0, 0, 0, 0, 0, 80, 113, 201, 61, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 145, 237, 252, 62, 0, 0, 0, 0, - 0, 0, 0, 0, 38, 0, 255, 255, 255, 255, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 112, 111, - }; +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.008196720853447914; - test_msg.uart_a.tx_buffer_level = 0; - test_msg.uart_a.tx_throughput = 0.0; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 2; - test_msg.uart_b.tx_throughput = 0.09836065769195557; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 38; - test_msg.uart_ftdi.tx_throughput = 0.49399998784065247; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.00819672085345 * 100), - 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected " - "0.00819672085345, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 0, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected 0.0, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 2) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 2, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.098360657692 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected " - "0.098360657692, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 38) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "38, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 0.493999987841 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "0.493999987841, is " - << last_msg_.uart_ftdi.tx_throughput; -} -class Test_auto_check_sbp_piksi_MsgUartStateDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_piksi_MsgUartStateDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_uart_state_depa_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_uart_state_depa_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_piksi_MsgUartStateDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 24, 0, 195, 4, 58, 166, 155, 68, 60, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 166, 155, 68, 60, 0, 0, 0, 0, - 0, 0, 0, 0, 2, 0, 236, 81, 168, 63, 0, 0, 0, 0, - 0, 0, 0, 0, 50, 0, 255, 255, 255, 255, 0, 0, 0, 0, - 0, 0, 0, 0, 255, 255, 255, 255, 22, 72, - }; + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; - sbp_msg_uart_state_depa_t test_msg{}; - test_msg.latency.avg = -1; - test_msg.latency.current = -1; - test_msg.latency.lmax = 0; - test_msg.latency.lmin = 0; - test_msg.uart_a.crc_error_count = 0; - test_msg.uart_a.io_error_count = 0; - test_msg.uart_a.rx_buffer_level = 0; - test_msg.uart_a.rx_throughput = 0.0; - test_msg.uart_a.tx_buffer_level = 2; - test_msg.uart_a.tx_throughput = 0.012000000104308128; - test_msg.uart_b.crc_error_count = 0; - test_msg.uart_b.io_error_count = 0; - test_msg.uart_b.rx_buffer_level = 0; - test_msg.uart_b.rx_throughput = 0.0; - test_msg.uart_b.tx_buffer_level = 2; - test_msg.uart_b.tx_throughput = 0.012000000104308128; - test_msg.uart_ftdi.crc_error_count = 0; - test_msg.uart_ftdi.io_error_count = 0; - test_msg.uart_ftdi.rx_buffer_level = 0; - test_msg.uart_ftdi.rx_throughput = 0.0; - test_msg.uart_ftdi.tx_buffer_level = 50; - test_msg.uart_ftdi.tx_throughput = 1.315000057220459; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.latency.avg, -1) - << "incorrect value for last_msg_.latency.avg, expected -1, is " - << last_msg_.latency.avg; - EXPECT_EQ(last_msg_.latency.current, -1) - << "incorrect value for last_msg_.latency.current, expected -1, is " - << last_msg_.latency.current; - EXPECT_EQ(last_msg_.latency.lmax, 0) - << "incorrect value for last_msg_.latency.lmax, expected 0, is " - << last_msg_.latency.lmax; - EXPECT_EQ(last_msg_.latency.lmin, 0) - << "incorrect value for last_msg_.latency.lmin, expected 0, is " - << last_msg_.latency.lmin; - EXPECT_EQ(last_msg_.uart_a.crc_error_count, 0) - << "incorrect value for last_msg_.uart_a.crc_error_count, expected 0, is " - << last_msg_.uart_a.crc_error_count; - EXPECT_EQ(last_msg_.uart_a.io_error_count, 0) - << "incorrect value for last_msg_.uart_a.io_error_count, expected 0, is " - << last_msg_.uart_a.io_error_count; - EXPECT_EQ(last_msg_.uart_a.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_a.rx_buffer_level, expected 0, is " - << last_msg_.uart_a.rx_buffer_level; - EXPECT_LT((last_msg_.uart_a.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_a.rx_throughput, expected 0.0, is " - << last_msg_.uart_a.rx_throughput; - EXPECT_EQ(last_msg_.uart_a.tx_buffer_level, 2) - << "incorrect value for last_msg_.uart_a.tx_buffer_level, expected 2, is " - << last_msg_.uart_a.tx_buffer_level; - EXPECT_LT((last_msg_.uart_a.tx_throughput * 100 - 0.0120000001043 * 100), - 0.05) - << "incorrect value for last_msg_.uart_a.tx_throughput, expected " - "0.0120000001043, is " - << last_msg_.uart_a.tx_throughput; - EXPECT_EQ(last_msg_.uart_b.crc_error_count, 0) - << "incorrect value for last_msg_.uart_b.crc_error_count, expected 0, is " - << last_msg_.uart_b.crc_error_count; - EXPECT_EQ(last_msg_.uart_b.io_error_count, 0) - << "incorrect value for last_msg_.uart_b.io_error_count, expected 0, is " - << last_msg_.uart_b.io_error_count; - EXPECT_EQ(last_msg_.uart_b.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_b.rx_buffer_level, expected 0, is " - << last_msg_.uart_b.rx_buffer_level; - EXPECT_LT((last_msg_.uart_b.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_b.rx_throughput, expected 0.0, is " - << last_msg_.uart_b.rx_throughput; - EXPECT_EQ(last_msg_.uart_b.tx_buffer_level, 2) - << "incorrect value for last_msg_.uart_b.tx_buffer_level, expected 2, is " - << last_msg_.uart_b.tx_buffer_level; - EXPECT_LT((last_msg_.uart_b.tx_throughput * 100 - 0.0120000001043 * 100), - 0.05) - << "incorrect value for last_msg_.uart_b.tx_throughput, expected " - "0.0120000001043, is " - << last_msg_.uart_b.tx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.crc_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.crc_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.crc_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.io_error_count, 0) - << "incorrect value for last_msg_.uart_ftdi.io_error_count, expected 0, " - "is " - << last_msg_.uart_ftdi.io_error_count; - EXPECT_EQ(last_msg_.uart_ftdi.rx_buffer_level, 0) - << "incorrect value for last_msg_.uart_ftdi.rx_buffer_level, expected 0, " - "is " - << last_msg_.uart_ftdi.rx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.rx_throughput * 100 - 0.0 * 100), 0.05) - << "incorrect value for last_msg_.uart_ftdi.rx_throughput, expected 0.0, " - "is " - << last_msg_.uart_ftdi.rx_throughput; - EXPECT_EQ(last_msg_.uart_ftdi.tx_buffer_level, 50) - << "incorrect value for last_msg_.uart_ftdi.tx_buffer_level, expected " - "50, is " - << last_msg_.uart_ftdi.tx_buffer_level; - EXPECT_LT((last_msg_.uart_ftdi.tx_throughput * 100 - 1.31500005722 * 100), - 0.05) - << "incorrect value for last_msg_.uart_ftdi.tx_throughput, expected " - "1.31500005722, is " - << last_msg_.uart_ftdi.tx_throughput; + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } } + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartStateDepA2 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgUartStateDepA2() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 0); + assign(test_msg_.uart_a.tx_throughput, 0.0); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 0); + assign(test_msg_.uart_b.tx_throughput, 0.0); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 10); + assign(test_msg_.uart_ftdi.tx_throughput, 0.13899999856948853); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x24c6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { + 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 4, 86, 14, 62, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 198, 36, + }; + uint8_t encoded_payload_[58] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 86, + 14, 62, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartStateDepA3 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgUartStateDepA3() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 0); + assign(test_msg_.uart_a.tx_throughput, 0.0); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 0); + assign(test_msg_.uart_b.tx_throughput, 0.0); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 0); + assign(test_msg_.uart_ftdi.tx_throughput, 0.06599999964237213); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6e41; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { + 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, 43, 135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, 65, 110, + }; + uint8_t encoded_payload_[58] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 43, + 135, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartStateDepA4 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgUartStateDepA4() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.008196720853447914); + assign(test_msg_.uart_a.tx_buffer_level, 0); + assign(test_msg_.uart_a.tx_throughput, 0.0); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 2); + assign(test_msg_.uart_b.tx_throughput, 0.09836065769195557); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 38); + assign(test_msg_.uart_ftdi.tx_throughput, 0.49399998784065247); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6f70; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { + 85, 24, 0, 195, 4, 58, 0, 0, 0, 0, 138, 75, 6, 60, + 0, 0, 0, 0, 0, 0, 80, 113, 201, 61, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 145, 237, 252, 62, 0, 0, 0, 0, + 0, 0, 0, 0, 38, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 112, 111, + }; + uint8_t encoded_payload_[58] = { + 0, 0, 0, 0, 138, 75, 6, 60, 0, 0, 0, 0, 0, 0, 80, + 113, 201, 61, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 145, 237, + 252, 62, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_piksi_MsgUartStateDepA5 : public ::testing::Test { + public: + Testauto_check_sbp_piksi_MsgUartStateDepA5() { + assign(test_msg_.latency.avg, -1); + assign(test_msg_.latency.current, -1); + assign(test_msg_.latency.lmax, 0); + assign(test_msg_.latency.lmin, 0); + assign(test_msg_.uart_a.crc_error_count, 0); + assign(test_msg_.uart_a.io_error_count, 0); + assign(test_msg_.uart_a.rx_buffer_level, 0); + assign(test_msg_.uart_a.rx_throughput, 0.0); + assign(test_msg_.uart_a.tx_buffer_level, 2); + assign(test_msg_.uart_a.tx_throughput, 0.012000000104308128); + assign(test_msg_.uart_b.crc_error_count, 0); + assign(test_msg_.uart_b.io_error_count, 0); + assign(test_msg_.uart_b.rx_buffer_level, 0); + assign(test_msg_.uart_b.rx_throughput, 0.0); + assign(test_msg_.uart_b.tx_buffer_level, 2); + assign(test_msg_.uart_b.tx_throughput, 0.012000000104308128); + assign(test_msg_.uart_ftdi.crc_error_count, 0); + assign(test_msg_.uart_ftdi.io_error_count, 0); + assign(test_msg_.uart_ftdi.rx_buffer_level, 0); + assign(test_msg_.uart_ftdi.rx_throughput, 0.0); + assign(test_msg_.uart_ftdi.tx_buffer_level, 50); + assign(test_msg_.uart_ftdi.tx_throughput, 1.315000057220459); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_uart_state_depa_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgUartStateDepa, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_uart_state_depa_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgUartStateDepa); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->uart_state_depa, + sizeof(msg->uart_state_depa)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_uart_state_depa_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.uart_state_depa, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgUartStateDepa); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x4816; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 58; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_uart_state_depa_t &lesser, + const sbp_msg_uart_state_depa_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_uart_state_depa_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_uart_state_depa_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_uart_state_depa_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgUartStateDepa, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_uart_state_depa_t test_msg_{}; + uint8_t encoded_frame_[58 + 8] = { + 85, 24, 0, 195, 4, 58, 166, 155, 68, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 166, 155, 68, 60, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 236, 81, 168, 63, 0, 0, 0, 0, + 0, 0, 0, 0, 50, 0, 255, 255, 255, 255, 0, 0, 0, 0, + 0, 0, 0, 0, 255, 255, 255, 255, 22, 72, + }; + uint8_t encoded_payload_[58] = { + 166, 155, 68, 60, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 166, + 155, 68, 60, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 236, 81, + 168, 63, 0, 0, 0, 0, 0, 0, 0, 0, 50, 0, 255, 255, 255, + 255, 0, 0, 0, 0, 0, 0, 0, 0, 255, 255, 255, 255, + }; +}; + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_uart_state_depa_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgUartStateDepa, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgUartStateDepa, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + EXPECT_EQ(sbp_msg_uart_state_depa_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + + for (uint8_t i = 0; i < 58; i++) { + EXPECT_EQ( + sbp_msg_uart_state_depa_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgUartStateDepa, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_uart_state_depa_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_uart_state_depa_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgUartStateDepa, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.avg, greater.latency.avg); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.current, greater.latency.current); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmax, greater.latency.lmax); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.latency.lmin, greater.latency.lmin); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.crc_error_count, + greater.uart_a.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.io_error_count, + greater.uart_a.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_buffer_level, + greater.uart_a.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.rx_throughput, + greater.uart_a.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_buffer_level, + greater.uart_a.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_a.tx_throughput, + greater.uart_a.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.crc_error_count, + greater.uart_b.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.io_error_count, + greater.uart_b.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_buffer_level, + greater.uart_b.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.rx_throughput, + greater.uart_b.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_buffer_level, + greater.uart_b.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_b.tx_throughput, + greater.uart_b.tx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.crc_error_count, + greater.uart_ftdi.crc_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.io_error_count, + greater.uart_ftdi.io_error_count); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_buffer_level, + greater.uart_ftdi.rx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.rx_throughput, + greater.uart_ftdi.rx_throughput); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_buffer_level, + greater.uart_ftdi.tx_buffer_level); + comparison_tests(lesser, greater); + } + { + sbp_msg_uart_state_depa_t lesser = info.test_msg; + sbp_msg_uart_state_depa_t greater = info.test_msg; + make_lesser_greater(lesser.uart_ftdi.tx_throughput, + greater.uart_ftdi.tx_throughput); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgUartStateDepa); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_UART_STATE_DEPA"); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_uart_state_depa_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_uart_state_depa_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.uart_state_depa, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.uart_state_depa, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[58]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 58); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 58), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_uart_state_depa_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 58); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgUartStateDepa, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_piksi_MsgUartStateDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgUartStateDepa, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_sbas_MsgSbasRaw.cc b/c/test/cpp/auto_check_sbp_sbas_MsgSbasRaw.cc index 0349576f51..21ce5132bb 100644 --- a/c/test/cpp/auto_check_sbp_sbas_MsgSbasRaw.cc +++ b/c/test/cpp/auto_check_sbp_sbas_MsgSbasRaw.cc @@ -16,234 +16,822 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_sbas_MsgSbasRaw0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_sbas_MsgSbasRaw0 : public ::testing::Test { public: - Test_auto_check_sbp_sbas_MsgSbasRaw0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_sbas_MsgSbasRaw0() { + assign(test_msg_.data[0], 23); + + assign(test_msg_.data[1], 255); + + assign(test_msg_.data[2], 0); + + assign(test_msg_.data[3], 23); + + assign(test_msg_.data[4], 255); + + assign(test_msg_.data[5], 0); + + assign(test_msg_.data[6], 23); + + assign(test_msg_.data[7], 255); + + assign(test_msg_.data[8], 127); + + assign(test_msg_.data[9], 240); + + assign(test_msg_.data[10], 2); + + assign(test_msg_.data[11], 255); + + assign(test_msg_.data[12], 192); + + assign(test_msg_.data[13], 3); + + assign(test_msg_.data[14], 127); + + assign(test_msg_.data[15], 247); + + assign(test_msg_.data[16], 255); + + assign(test_msg_.data[17], 127); + + assign(test_msg_.data[18], 247); + + assign(test_msg_.data[19], 255); + + assign(test_msg_.data[20], 229); + + assign(test_msg_.data[21], 229); + + assign(test_msg_.data[22], 238); + + assign(test_msg_.data[23], 170); + + assign(test_msg_.data[24], 175); + + assign(test_msg_.data[25], 255); + + assign(test_msg_.data[26], 240); + assign(test_msg_.message_type, 4); + assign(test_msg_.sid.code, 2); + assign(test_msg_.sid.sat, 131); + assign(test_msg_.tow, 501867721); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_sbas_raw_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_sbas_raw_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSbasRaw, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_sbas_raw_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSbasRaw); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->sbas_raw, sizeof(msg->sbas_raw)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_sbas_raw_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.sbas_raw, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSbasRaw); + info.sender_id = 51228; + info.preamble = 0x55; + info.crc = 0xea7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 34; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_sbas_raw_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_sbas_raw_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_sbas_raw_t &lesser, + const sbp_msg_sbas_raw_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_sbas_raw_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_sbas_raw_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_sbas_raw_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_sbas_raw_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSbasRaw, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgSbasRaw, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSbasRaw, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSbasRaw, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_sbas_MsgSbasRaw0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_sbas_raw_t test_msg_{}; + uint8_t encoded_frame_[34 + 8] = { 85, 119, 119, 28, 200, 34, 131, 2, 201, 228, 233, 29, 4, 23, 255, 0, 23, 255, 0, 23, 255, 127, 240, 2, 255, 192, 3, 127, 247, 255, 127, 247, 255, 229, 229, 238, 170, 175, 255, 240, 167, 14, }; + uint8_t encoded_payload_[34] = { + 131, 2, 201, 228, 233, 29, 4, 23, 255, 0, 23, 255, + 0, 23, 255, 127, 240, 2, 255, 192, 3, 127, 247, 255, + 127, 247, 255, 229, 229, 238, 170, 175, 255, 240, + }; +}; + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_sbas_raw_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSbasRaw, &info.test_msg_wrapped), + info.payload_len); +} - sbp_msg_sbas_raw_t test_msg{}; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_sbas_raw_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgSbasRaw, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} - test_msg.data[0] = 23; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[34]; - test_msg.data[1] = 255; + EXPECT_EQ( + sbp_msg_sbas_raw_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + + for (uint8_t i = 0; i < 34; i++) { + EXPECT_EQ(sbp_msg_sbas_raw_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sbas_raw_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_sbas_raw_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSbasRaw, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.data[2] = 0; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_sbas_raw_t msg{}; - test_msg.data[3] = 23; + EXPECT_EQ(sbp_msg_sbas_raw_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_sbas_raw_t msg{}; - test_msg.data[4] = 255; + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; - test_msg.data[5] = 0; + EXPECT_EQ( + sbp_msg_sbas_raw_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} - test_msg.data[6] = 23; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.data[7] = 255; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.data[8] = 127; + CHandler handler{&state}; - test_msg.data[9] = 240; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.data[10] = 2; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.data[11] = 255; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.data[12] = 192; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.data[13] = 3; + EXPECT_EQ(sbp_msg_sbas_raw_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.data[14] = 127; +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.data[15] = 247; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.data[16] = 255; - - test_msg.data[17] = 127; - - test_msg.data[18] = 247; - - test_msg.data[19] = 255; - - test_msg.data[20] = 229; - - test_msg.data[21] = 229; - - test_msg.data[22] = 238; - - test_msg.data[23] = 170; - - test_msg.data[24] = 175; - - test_msg.data[25] = 255; - - test_msg.data[26] = 240; - test_msg.message_type = 4; - test_msg.sid.code = 2; - test_msg.sid.sat = 131; - test_msg.tow = 501867721; - - EXPECT_EQ(send_message(51228, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 51228); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.data[0], 23) - << "incorrect value for last_msg_.data[0], expected 23, is " - << last_msg_.data[0]; - EXPECT_EQ(last_msg_.data[1], 255) - << "incorrect value for last_msg_.data[1], expected 255, is " - << last_msg_.data[1]; - EXPECT_EQ(last_msg_.data[2], 0) - << "incorrect value for last_msg_.data[2], expected 0, is " - << last_msg_.data[2]; - EXPECT_EQ(last_msg_.data[3], 23) - << "incorrect value for last_msg_.data[3], expected 23, is " - << last_msg_.data[3]; - EXPECT_EQ(last_msg_.data[4], 255) - << "incorrect value for last_msg_.data[4], expected 255, is " - << last_msg_.data[4]; - EXPECT_EQ(last_msg_.data[5], 0) - << "incorrect value for last_msg_.data[5], expected 0, is " - << last_msg_.data[5]; - EXPECT_EQ(last_msg_.data[6], 23) - << "incorrect value for last_msg_.data[6], expected 23, is " - << last_msg_.data[6]; - EXPECT_EQ(last_msg_.data[7], 255) - << "incorrect value for last_msg_.data[7], expected 255, is " - << last_msg_.data[7]; - EXPECT_EQ(last_msg_.data[8], 127) - << "incorrect value for last_msg_.data[8], expected 127, is " - << last_msg_.data[8]; - EXPECT_EQ(last_msg_.data[9], 240) - << "incorrect value for last_msg_.data[9], expected 240, is " - << last_msg_.data[9]; - EXPECT_EQ(last_msg_.data[10], 2) - << "incorrect value for last_msg_.data[10], expected 2, is " - << last_msg_.data[10]; - EXPECT_EQ(last_msg_.data[11], 255) - << "incorrect value for last_msg_.data[11], expected 255, is " - << last_msg_.data[11]; - EXPECT_EQ(last_msg_.data[12], 192) - << "incorrect value for last_msg_.data[12], expected 192, is " - << last_msg_.data[12]; - EXPECT_EQ(last_msg_.data[13], 3) - << "incorrect value for last_msg_.data[13], expected 3, is " - << last_msg_.data[13]; - EXPECT_EQ(last_msg_.data[14], 127) - << "incorrect value for last_msg_.data[14], expected 127, is " - << last_msg_.data[14]; - EXPECT_EQ(last_msg_.data[15], 247) - << "incorrect value for last_msg_.data[15], expected 247, is " - << last_msg_.data[15]; - EXPECT_EQ(last_msg_.data[16], 255) - << "incorrect value for last_msg_.data[16], expected 255, is " - << last_msg_.data[16]; - EXPECT_EQ(last_msg_.data[17], 127) - << "incorrect value for last_msg_.data[17], expected 127, is " - << last_msg_.data[17]; - EXPECT_EQ(last_msg_.data[18], 247) - << "incorrect value for last_msg_.data[18], expected 247, is " - << last_msg_.data[18]; - EXPECT_EQ(last_msg_.data[19], 255) - << "incorrect value for last_msg_.data[19], expected 255, is " - << last_msg_.data[19]; - EXPECT_EQ(last_msg_.data[20], 229) - << "incorrect value for last_msg_.data[20], expected 229, is " - << last_msg_.data[20]; - EXPECT_EQ(last_msg_.data[21], 229) - << "incorrect value for last_msg_.data[21], expected 229, is " - << last_msg_.data[21]; - EXPECT_EQ(last_msg_.data[22], 238) - << "incorrect value for last_msg_.data[22], expected 238, is " - << last_msg_.data[22]; - EXPECT_EQ(last_msg_.data[23], 170) - << "incorrect value for last_msg_.data[23], expected 170, is " - << last_msg_.data[23]; - EXPECT_EQ(last_msg_.data[24], 175) - << "incorrect value for last_msg_.data[24], expected 175, is " - << last_msg_.data[24]; - EXPECT_EQ(last_msg_.data[25], 255) - << "incorrect value for last_msg_.data[25], expected 255, is " - << last_msg_.data[25]; - EXPECT_EQ(last_msg_.data[26], 240) - << "incorrect value for last_msg_.data[26], expected 240, is " - << last_msg_.data[26]; - EXPECT_EQ(last_msg_.message_type, 4) - << "incorrect value for last_msg_.message_type, expected 4, is " - << last_msg_.message_type; - EXPECT_EQ(last_msg_.sid.code, 2) - << "incorrect value for last_msg_.sid.code, expected 2, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.sat, 131) - << "incorrect value for last_msg_.sid.sat, expected 131, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.tow, 501867721) - << "incorrect value for last_msg_.tow, expected 501867721, is " - << last_msg_.tow; + EXPECT_EQ(sbp_message_send(&state, SbpMsgSbasRaw, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[0], greater.data[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[1], greater.data[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[2], greater.data[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[3], greater.data[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[4], greater.data[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[5], greater.data[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[6], greater.data[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[7], greater.data[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[8], greater.data[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[9], greater.data[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[10], greater.data[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[11], greater.data[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[12], greater.data[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[13], greater.data[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[14], greater.data[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[15], greater.data[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[16], greater.data[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[17], greater.data[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[18], greater.data[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[19], greater.data[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[20], greater.data[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[21], greater.data[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[22], greater.data[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[23], greater.data[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[24], greater.data[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[25], greater.data[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.data[26], greater.data[26]); + comparison_tests(lesser, greater); + } + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.message_type, greater.message_type); + comparison_tests(lesser, greater); + } + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_sbas_raw_t lesser = info.test_msg; + sbp_msg_sbas_raw_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgSbasRaw); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_SBAS_RAW"); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_sbas_raw_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_sbas_raw_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.sbas_raw, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.sbas_raw, info.test_msg); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[34]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 34); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 34), 0); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sbas_raw_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 34); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSbasRaw, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_sbas_MsgSbasRaw0, SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgSbasRaw, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexDone.cc b/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexDone.cc index 596be8ccc5..99c7066a89 100644 --- a/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexDone.cc +++ b/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexDone.cc @@ -16,82 +16,561 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexDone0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0 + : public ::testing::Test { public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexDone0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0() {} + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_done_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_done_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_done_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexDone, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_done_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexDone); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_done, + sizeof(msg->settings_read_by_index_done)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_done_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_done, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexDone); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x3aa3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 0; + + return info; } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; + protected: + void comparison_tests(const sbp_msg_settings_read_by_index_done_t &lesser, + const sbp_msg_settings_read_by_index_done_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_done_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_done_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_done_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexDone, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexDone, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexDone, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexDone, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } } - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_done_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); } - sbp_msg_settings_read_by_index_done_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexDone0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_settings_read_by_index_done_t test_msg_{}; + uint8_t encoded_frame_[0 + 8] = { 85, 166, 0, 246, 215, 0, 163, 58, }; + uint8_t encoded_payload_[1] = {}; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_done_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexDone, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[1]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 0); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 0), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexDone, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 0); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 0), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[1]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 0), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_done_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 0); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexDone, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 0); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_done_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_settings_read_by_index_done_t test_msg{}; +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_done_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexDone, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexDone); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_DONE"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_done_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_done_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_done, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_done, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[1]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 0); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 0), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_done_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 0); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexDone, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexDone0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexDone, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexResp.cc b/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexResp.cc index fb147e7f3b..2ad9fad309 100644 --- a/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexResp.cc +++ b/c/test/cpp/auto_check_sbp_settings_MsgSettingsReadByIndexResp.cc @@ -16,67 +16,292 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0 + : public ::testing::Test { public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0() { + assign(test_msg_.index, 0); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "telemetry_radio")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "configuration_string")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); + EXPECT_EQ( + sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg_), + 76); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_resp, + sizeof(msg->settings_read_by_index_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexResp); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xe9f8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 78; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_settings_read_by_index_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_settings_read_by_index_resp_t &lesser, + const sbp_msg_settings_read_by_index_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_settings_read_by_index_resp_t test_msg_{}; + uint8_t encoded_frame_[78 + 8] = { 85, 167, 0, 246, 215, 78, 0, 0, 116, 101, 108, 101, 109, 101, 116, 114, 121, 95, 114, 97, 100, 105, 111, 0, 99, 111, 110, 102, 105, 103, 117, 114, 97, 116, 105, 111, 110, 95, 115, 116, 114, 105, 110, 103, 0, @@ -84,466 +309,3940 @@ TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp0, Test) { 84, 83, 50, 61, 49, 50, 56, 44, 65, 84, 83, 53, 61, 48, 44, 65, 84, 38, 87, 44, 65, 84, 90, 0, 248, 233, }; + uint8_t encoded_payload_[78] = { + 0, 0, 116, 101, 108, 101, 109, 101, 116, 114, 121, 95, 114, + 97, 100, 105, 111, 0, 99, 111, 110, 102, 105, 103, 117, 114, + 97, 116, 105, 111, 110, 95, 115, 116, 114, 105, 110, 103, 0, + 65, 84, 38, 70, 44, 65, 84, 83, 49, 61, 49, 49, 53, + 44, 65, 84, 83, 50, 61, 49, 50, 56, 44, 65, 84, 83, + 53, 61, 48, 44, 65, 84, 38, 87, 44, 65, 84, 90, 0, + }; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[78]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 78); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 78), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 78); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 78), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[78]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 78), 0); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[78]; + + for (uint8_t i = 0; i < 78; i++) { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 78); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 78); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_SETTINGS_READ_BY_INDEX_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_settings_read_by_index_resp_t t{}; + // return sbp_msg_settings_read_by_index_resp_encoded_len(&t); }(); + overhead += 1; + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.index, greater.index); + comparison_tests(lesser, greater); + } + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.setting, greater.setting); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_RESP"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[78]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 78); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 78), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 78); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } - sbp_msg_settings_read_by_index_resp_t test_msg{}; - test_msg.index = 0; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting + : public Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0 {}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + StringInit) { + sbp_msg_settings_read_by_index_resp_t t{}; + sbp_msg_settings_read_by_index_resp_setting_init(&t); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + IsValid) { + sbp_msg_settings_read_by_index_resp_t t{}; EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "telemetry_radio")); + &t, "telemetry_radio")); EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "configuration_string")); + &t, "configuration_string")); EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg), - 76); - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.index, 0) - << "incorrect value for last_msg_.index, expected 0, is " - << last_msg_.index; - - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&last_msg_), - 76); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 0), - "telemetry_radio"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 1), - "configuration_string"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 2), - "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ"); -} -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + &t, "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 76); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + SpaceRemaining) { + sbp_msg_settings_read_by_index_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "telemetry_radio")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "configuration_string")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 76); + size_t assigned_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + CountSections) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections( + &info.test_msg), + 3); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + AddSectionPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "telemetry_radio")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "configuration_string")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "telemetry_radio"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "configuration_string"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + AddSectionVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "telemetry_radio")); } - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_settings_read_by_index_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "configuration_string")); + } -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp1, Test) { - uint8_t encoded_frame[] = { - 85, 167, 0, 246, 215, 35, 1, 0, 117, 97, 114, 116, 95, 102, 116, - 100, 105, 0, 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, 117, - 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, 167, 243, - }; + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); + } - sbp_msg_settings_read_by_index_resp_t test_msg{}; - test_msg.index = 1; + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "uart_ftdi")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section(&test_msg, - "mode")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section(&test_msg, - "SBP")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "enum:SBP,NMEA")); - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg), - 33); - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.index, 1) - << "incorrect value for last_msg_.index, expected 1, is " - << last_msg_.index; - - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&last_msg_), - 33); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 0), - "uart_ftdi"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 1), - "mode"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 2), - "SBP"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 3), - "enum:SBP,NMEA"); -} -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "telemetry_radio"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "configuration_string"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + Append) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "telemetry_radio"; + char part2[] = "telemetry_radio"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append(&t, part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_append(&t, &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "telemetry_radio"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + AppendPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "telemetry_radio"; + char part2[] = "telemetry_radio"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "telemetry_radio"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + AppendVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "telemetry_radio"; + char part2[] = "telemetry_radio"; + part1[1] = 0; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", part1)); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", &part2[1])); } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "telemetry_radio"); +} - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_settings_read_by_index_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp0_setting, + SectionStrlen) { + auto info = get_test_msg_info(); -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp2, Test) { - uint8_t encoded_frame[] = { - 85, 167, 0, 246, 215, 35, 2, 0, 117, 97, 114, 116, 95, 102, 116, - 100, 105, 0, 115, 98, 112, 95, 109, 101, 115, 115, 97, 103, 101, 95, - 109, 97, 115, 107, 0, 54, 53, 53, 51, 53, 0, 4, 56, - }; + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 0), + strlen("telemetry_radio")); - sbp_msg_settings_read_by_index_resp_t test_msg{}; - test_msg.index = 2; + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 1), + strlen("configuration_string")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "uart_ftdi")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "sbp_message_mask")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section(&test_msg, - "65535")); - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg), - 33); - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.index, 2) - << "incorrect value for last_msg_.index, expected 2, is " - << last_msg_.index; - - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&last_msg_), - 33); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 0), - "uart_ftdi"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 1), - "sbp_message_mask"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 2), - "65535"); -} -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 2), + strlen("AT&F,ATS1=115,ATS2=128,ATS5=0,AT&W,ATZ")); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1 + : public ::testing::Test { public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1() { + assign(test_msg_.index, 1); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "uart_ftdi")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "mode")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "enum:SBP,NMEA")); + EXPECT_EQ( + sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg_), + 33); } - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_settings_read_by_index_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp3, Test) { - uint8_t encoded_frame[] = { - 85, 167, 0, 246, 215, 29, 3, 0, 117, 97, 114, 116, 95, - 102, 116, 100, 105, 0, 98, 97, 117, 100, 114, 97, 116, 101, - 0, 49, 48, 48, 48, 48, 48, 48, 0, 242, 146, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_settings_read_by_index_resp_t test_msg{}; - test_msg.index = 3; + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "uart_ftdi")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "baudrate")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "1000000")); - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg), - 27); - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.index, 3) - << "incorrect value for last_msg_.index, expected 3, is " - << last_msg_.index; - - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&last_msg_), - 27); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 0), - "uart_ftdi"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 1), - "baudrate"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 2), - "1000000"); -} -class Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_resp, + sizeof(msg->settings_read_by_index_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexResp); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xf3a7; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 35; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_settings_read_by_index_resp_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_settings_read_by_index_resp_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_settings_read_by_index_resp_t &lesser, + const sbp_msg_settings_read_by_index_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); -TEST_F(Test_auto_check_sbp_settings_MsgSettingsReadByIndexResp4, Test) { - uint8_t encoded_frame[] = { - 85, 167, 0, 246, 215, 36, 4, 0, 117, 97, 114, 116, 95, 117, 97, - 114, 116, 97, 0, 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, - 117, 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, 22, 4, - }; + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_resp_cmp(&greater, &lesser), 0); - sbp_msg_settings_read_by_index_resp_t test_msg{}; - test_msg.index = 4; + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_lesser), + 0); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "uart_uarta")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section(&test_msg, - "mode")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section(&test_msg, - "SBP")); - EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( - &test_msg, "enum:SBP,NMEA")); - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg), - 34); - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.index, 4) - << "incorrect value for last_msg_.index, expected 4, is " - << last_msg_.index; - - EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&last_msg_), - 34); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 0), - "uart_uarta"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 1), - "mode"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 2), - "SBP"); - EXPECT_STREQ( - sbp_msg_settings_read_by_index_resp_setting_get_section(&last_msg_, 3), - "enum:SBP,NMEA"); -} + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_settings_read_by_index_resp_t test_msg_{}; + uint8_t encoded_frame_[35 + 8] = { + 85, 167, 0, 246, 215, 35, 1, 0, 117, 97, 114, 116, 95, 102, 116, + 100, 105, 0, 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, 117, + 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, 167, 243, + }; + uint8_t encoded_payload_[35] = { + 1, 0, 117, 97, 114, 116, 95, 102, 116, 100, 105, 0, + 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, 117, + 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, + }; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + for (uint8_t i = 0; i < 35; i++) { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_SETTINGS_READ_BY_INDEX_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_settings_read_by_index_resp_t t{}; + // return sbp_msg_settings_read_by_index_resp_encoded_len(&t); }(); + overhead += 1; + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.index, greater.index); + comparison_tests(lesser, greater); + } + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.setting, greater.setting); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_RESP"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting + : public Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1 {}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + StringInit) { + sbp_msg_settings_read_by_index_resp_t t{}; + sbp_msg_settings_read_by_index_resp_setting_init(&t); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + IsValid) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "mode")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "enum:SBP,NMEA")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 33); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + SpaceRemaining) { + sbp_msg_settings_read_by_index_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "mode")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "enum:SBP,NMEA")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 33); + size_t assigned_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + CountSections) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections( + &info.test_msg), + 4); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + AddSectionPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "uart_ftdi")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "mode")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "SBP")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "enum:SBP,NMEA")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 4); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "mode"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "SBP"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 3), + "enum:SBP,NMEA"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + AddSectionVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "uart_ftdi")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "mode")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "SBP")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "enum:SBP,NMEA")); + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 4); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "mode"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "SBP"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 3), + "enum:SBP,NMEA"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + Append) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append(&t, part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_append(&t, &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + AppendPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + AppendVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", part1)); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", &part2[1])); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp1_setting, + SectionStrlen) { + auto info = get_test_msg_info(); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 0), + strlen("uart_ftdi")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 1), + strlen("mode")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 2), + strlen("SBP")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 3), + strlen("enum:SBP,NMEA")); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2 + : public ::testing::Test { + public: + Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2() { + assign(test_msg_.index, 2); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "uart_ftdi")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "sbp_message_mask")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "65535")); + EXPECT_EQ( + sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg_), + 33); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_resp, + sizeof(msg->settings_read_by_index_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexResp); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x3804; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 35; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_settings_read_by_index_resp_t &lesser, + const sbp_msg_settings_read_by_index_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_settings_read_by_index_resp_t test_msg_{}; + uint8_t encoded_frame_[35 + 8] = { + 85, 167, 0, 246, 215, 35, 2, 0, 117, 97, 114, 116, 95, 102, 116, + 100, 105, 0, 115, 98, 112, 95, 109, 101, 115, 115, 97, 103, 101, 95, + 109, 97, 115, 107, 0, 54, 53, 53, 51, 53, 0, 4, 56, + }; + uint8_t encoded_payload_[35] = { + 2, 0, 117, 97, 114, 116, 95, 102, 116, 100, 105, 0, + 115, 98, 112, 95, 109, 101, 115, 115, 97, 103, 101, 95, + 109, 97, 115, 107, 0, 54, 53, 53, 51, 53, 0, + }; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + + for (uint8_t i = 0; i < 35; i++) { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_SETTINGS_READ_BY_INDEX_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_settings_read_by_index_resp_t t{}; + // return sbp_msg_settings_read_by_index_resp_encoded_len(&t); }(); + overhead += 1; + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.index, greater.index); + comparison_tests(lesser, greater); + } + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.setting, greater.setting); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_RESP"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[35]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 35); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 35), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 35); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting + : public Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2 {}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + StringInit) { + sbp_msg_settings_read_by_index_resp_t t{}; + sbp_msg_settings_read_by_index_resp_setting_init(&t); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + IsValid) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "sbp_message_mask")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "65535")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 33); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + SpaceRemaining) { + sbp_msg_settings_read_by_index_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "sbp_message_mask")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "65535")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 33); + size_t assigned_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + CountSections) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections( + &info.test_msg), + 3); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + AddSectionPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "uart_ftdi")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "sbp_message_mask")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "65535")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "sbp_message_mask"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "65535"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + AddSectionVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "uart_ftdi")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "sbp_message_mask")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "65535")); + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "sbp_message_mask"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "65535"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + Append) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append(&t, part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_append(&t, &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + AppendPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + AppendVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", part1)); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", &part2[1])); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp2_setting, + SectionStrlen) { + auto info = get_test_msg_info(); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 0), + strlen("uart_ftdi")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 1), + strlen("sbp_message_mask")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 2), + strlen("65535")); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3 + : public ::testing::Test { + public: + Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3() { + assign(test_msg_.index, 3); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "uart_ftdi")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "baudrate")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "1000000")); + EXPECT_EQ( + sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg_), + 27); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_resp, + sizeof(msg->settings_read_by_index_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexResp); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x92f2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 29; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_settings_read_by_index_resp_t &lesser, + const sbp_msg_settings_read_by_index_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_settings_read_by_index_resp_t test_msg_{}; + uint8_t encoded_frame_[29 + 8] = { + 85, 167, 0, 246, 215, 29, 3, 0, 117, 97, 114, 116, 95, + 102, 116, 100, 105, 0, 98, 97, 117, 100, 114, 97, 116, 101, + 0, 49, 48, 48, 48, 48, 48, 48, 0, 242, 146, + }; + uint8_t encoded_payload_[29] = { + 3, 0, 117, 97, 114, 116, 95, 102, 116, 100, 105, 0, 98, 97, 117, + 100, 114, 97, 116, 101, 0, 49, 48, 48, 48, 48, 48, 48, 0, + }; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + + for (uint8_t i = 0; i < 29; i++) { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_SETTINGS_READ_BY_INDEX_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_settings_read_by_index_resp_t t{}; + // return sbp_msg_settings_read_by_index_resp_encoded_len(&t); }(); + overhead += 1; + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.index, greater.index); + comparison_tests(lesser, greater); + } + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.setting, greater.setting); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_RESP"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[29]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 29); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 29), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 29); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting + : public Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3 {}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + StringInit) { + sbp_msg_settings_read_by_index_resp_t t{}; + sbp_msg_settings_read_by_index_resp_setting_init(&t); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + IsValid) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "baudrate")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "1000000")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 27); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + SpaceRemaining) { + sbp_msg_settings_read_by_index_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "uart_ftdi")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "baudrate")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "1000000")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 27); + size_t assigned_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + CountSections) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections( + &info.test_msg), + 3); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + AddSectionPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "uart_ftdi")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "baudrate")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "1000000")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "baudrate"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "1000000"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + AddSectionVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "uart_ftdi")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "baudrate")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "1000000")); + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 3); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "baudrate"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "1000000"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + Append) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append(&t, part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_append(&t, &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + AppendPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + AppendVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_ftdi"; + char part2[] = "uart_ftdi"; + part1[1] = 0; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", part1)); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", &part2[1])); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_ftdi"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp3_setting, + SectionStrlen) { + auto info = get_test_msg_info(); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 0), + strlen("uart_ftdi")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 1), + strlen("baudrate")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 2), + strlen("1000000")); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4 + : public ::testing::Test { + public: + Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4() { + assign(test_msg_.index, 4); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "uart_uarta")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "mode")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &test_msg_, "enum:SBP,NMEA")); + EXPECT_EQ( + sbp_msg_settings_read_by_index_resp_setting_encoded_len(&test_msg_), + 34); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_settings_read_by_index_resp_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_settings_read_by_index_resp_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSettingsReadByIndexResp, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_settings_read_by_index_resp_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSettingsReadByIndexResp); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->settings_read_by_index_resp, + sizeof(msg->settings_read_by_index_resp)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_settings_read_by_index_resp_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.settings_read_by_index_resp, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSettingsReadByIndexResp); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x416; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 36; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_settings_read_by_index_resp_t &lesser, + const sbp_msg_settings_read_by_index_resp_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_settings_read_by_index_resp_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_settings_read_by_index_resp_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSettingsReadByIndexResp, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_settings_read_by_index_resp_t test_msg_{}; + uint8_t encoded_frame_[36 + 8] = { + 85, 167, 0, 246, 215, 36, 4, 0, 117, 97, 114, 116, 95, 117, 97, + 114, 116, 97, 0, 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, + 117, 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, 22, 4, + }; + uint8_t encoded_payload_[36] = { + 4, 0, 117, 97, 114, 116, 95, 117, 97, 114, 116, 97, + 0, 109, 111, 100, 101, 0, 83, 66, 80, 0, 101, 110, + 117, 109, 58, 83, 66, 80, 44, 78, 77, 69, 65, 0, + }; +}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[36]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 36); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 36), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSettingsReadByIndexResp, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 36); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 36), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[36]; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 36), 0); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[36]; + + for (uint8_t i = 0; i < 36; i++) { + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 36); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSettingsReadByIndexResp, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 36); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_SETTINGS_READ_BY_INDEX_RESP_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_settings_read_by_index_resp_t t{}; + // return sbp_msg_settings_read_by_index_resp_encoded_len(&t); }(); + overhead += 1; + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSettingsReadByIndexResp, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.index, greater.index); + comparison_tests(lesser, greater); + } + { + sbp_msg_settings_read_by_index_resp_t lesser = info.test_msg; + sbp_msg_settings_read_by_index_resp_t greater = info.test_msg; + make_lesser_greater(lesser.setting, greater.setting); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSettingsReadByIndexResp); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SETTINGS_READ_BY_INDEX_RESP"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_settings_read_by_index_resp_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_settings_read_by_index_resp_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.settings_read_by_index_resp, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.settings_read_by_index_resp, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[36]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 36); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 36), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_settings_read_by_index_resp_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 36); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSettingsReadByIndexResp, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting + : public Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4 {}; + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + StringInit) { + sbp_msg_settings_read_by_index_resp_t t{}; + sbp_msg_settings_read_by_index_resp_setting_init(&t); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + IsValid) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "uart_uarta")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "mode")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "enum:SBP,NMEA")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 34); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_valid(&t)); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + SpaceRemaining) { + sbp_msg_settings_read_by_index_resp_t t{}; + size_t empty_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "uart_uarta")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "mode")); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_add_section(&t, "SBP")); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section( + &t, "enum:SBP,NMEA")); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_encoded_len(&t), 34); + size_t assigned_space_remaining = + sbp_msg_settings_read_by_index_resp_setting_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + CountSections) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections( + &info.test_msg), + 4); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + AddSectionPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "uart_uarta")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "mode")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "SBP")); + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_add_section_printf( + &t, "%s", "enum:SBP,NMEA")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 4); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_uarta"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "mode"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "SBP"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 3), + "enum:SBP,NMEA"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + AddSectionVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "uart_uarta")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "mode")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "SBP")); + } + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_settings_read_by_index_resp_setting_add_section_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", "enum:SBP,NMEA")); + } + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_count_sections(&t), 4); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_uarta"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 1), + "mode"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 2), + "SBP"); + + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 3), + "enum:SBP,NMEA"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + Append) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_uarta"; + char part2[] = "uart_uarta"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append(&t, part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE( + sbp_msg_settings_read_by_index_resp_setting_append(&t, &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_uarta"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + AppendPrintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_uarta"; + char part2[] = "uart_uarta"; + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", part1)); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + EXPECT_TRUE(sbp_msg_settings_read_by_index_resp_setting_append_printf( + &t, "%s", &part2[1])); + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_uarta"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + AppendVprintf) { + sbp_msg_settings_read_by_index_resp_t t{}; + + char part1[] = "uart_uarta"; + char part2[] = "uart_uarta"; + part1[1] = 0; + + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", part1)); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + part1); + { + auto lambda = [&t](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_settings_read_by_index_resp_setting_append_vprintf( + &t, format, ap); + va_end(ap); + return ret; + }; + EXPECT_TRUE(lambda("%s", &part2[1])); + } + EXPECT_STREQ(sbp_msg_settings_read_by_index_resp_setting_get_section(&t, 0), + "uart_uarta"); +} + +TEST_F(Testauto_check_sbp_settings_MsgSettingsReadByIndexResp4_setting, + SectionStrlen) { + auto info = get_test_msg_info(); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 0), + strlen("uart_uarta")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 1), + strlen("mode")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 2), + strlen("SBP")); + + EXPECT_EQ(sbp_msg_settings_read_by_index_resp_setting_section_strlen( + &info.test_msg, 3), + strlen("enum:SBP,NMEA")); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgCertificateChain.cc b/c/test/cpp/auto_check_sbp_signing_MsgCertificateChain.cc index 0c11ddad02..28d8157dfc 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgCertificateChain.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgCertificateChain.cc @@ -16,66 +16,547 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgCertificateChain0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgCertificateChain0 : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgCertificateChain0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgCertificateChain0() { + assign(test_msg_.corrections_certificate[0], 20); + + assign(test_msg_.corrections_certificate[1], 21); + + assign(test_msg_.corrections_certificate[2], 22); + + assign(test_msg_.corrections_certificate[3], 23); + + assign(test_msg_.corrections_certificate[4], 24); + + assign(test_msg_.corrections_certificate[5], 25); + + assign(test_msg_.corrections_certificate[6], 26); + + assign(test_msg_.corrections_certificate[7], 27); + + assign(test_msg_.corrections_certificate[8], 28); + + assign(test_msg_.corrections_certificate[9], 29); + + assign(test_msg_.corrections_certificate[10], 10); + + assign(test_msg_.corrections_certificate[11], 11); + + assign(test_msg_.corrections_certificate[12], 12); + + assign(test_msg_.corrections_certificate[13], 13); + + assign(test_msg_.corrections_certificate[14], 14); + + assign(test_msg_.corrections_certificate[15], 15); + + assign(test_msg_.corrections_certificate[16], 16); + + assign(test_msg_.corrections_certificate[17], 17); + + assign(test_msg_.corrections_certificate[18], 18); + + assign(test_msg_.corrections_certificate[19], 19); + assign(test_msg_.expiration.day, 30); + assign(test_msg_.expiration.hours, 12); + assign(test_msg_.expiration.minutes, 34); + assign(test_msg_.expiration.month, 3); + assign(test_msg_.expiration.ns, 123456789); + assign(test_msg_.expiration.seconds, 59); + assign(test_msg_.expiration.year, 2024); + + assign(test_msg_.intermediate_certificate[0], 10); + + assign(test_msg_.intermediate_certificate[1], 11); + + assign(test_msg_.intermediate_certificate[2], 12); + + assign(test_msg_.intermediate_certificate[3], 13); + + assign(test_msg_.intermediate_certificate[4], 14); + + assign(test_msg_.intermediate_certificate[5], 15); + + assign(test_msg_.intermediate_certificate[6], 16); + + assign(test_msg_.intermediate_certificate[7], 17); + + assign(test_msg_.intermediate_certificate[8], 18); + + assign(test_msg_.intermediate_certificate[9], 19); + + assign(test_msg_.intermediate_certificate[10], 0); + + assign(test_msg_.intermediate_certificate[11], 1); + + assign(test_msg_.intermediate_certificate[12], 2); + + assign(test_msg_.intermediate_certificate[13], 3); + + assign(test_msg_.intermediate_certificate[14], 4); + + assign(test_msg_.intermediate_certificate[15], 5); + + assign(test_msg_.intermediate_certificate[16], 6); + + assign(test_msg_.intermediate_certificate[17], 7); + + assign(test_msg_.intermediate_certificate[18], 8); + + assign(test_msg_.intermediate_certificate[19], 9); + + assign(test_msg_.root_certificate[0], 0); + + assign(test_msg_.root_certificate[1], 1); + + assign(test_msg_.root_certificate[2], 2); + + assign(test_msg_.root_certificate[3], 3); + + assign(test_msg_.root_certificate[4], 4); + + assign(test_msg_.root_certificate[5], 5); + + assign(test_msg_.root_certificate[6], 6); + + assign(test_msg_.root_certificate[7], 7); + + assign(test_msg_.root_certificate[8], 8); + + assign(test_msg_.root_certificate[9], 9); + + assign(test_msg_.root_certificate[10], 10); + + assign(test_msg_.root_certificate[11], 11); + + assign(test_msg_.root_certificate[12], 12); + + assign(test_msg_.root_certificate[13], 13); + + assign(test_msg_.root_certificate[14], 14); + + assign(test_msg_.root_certificate[15], 15); + + assign(test_msg_.root_certificate[16], 16); + + assign(test_msg_.root_certificate[17], 17); + + assign(test_msg_.root_certificate[18], 18); + + assign(test_msg_.root_certificate[19], 19); + + assign(test_msg_.signature.data[0], 0); + + assign(test_msg_.signature.data[1], 1); + + assign(test_msg_.signature.data[2], 2); + + assign(test_msg_.signature.data[3], 3); + + assign(test_msg_.signature.data[4], 4); + + assign(test_msg_.signature.data[5], 5); + + assign(test_msg_.signature.data[6], 6); + + assign(test_msg_.signature.data[7], 7); + + assign(test_msg_.signature.data[8], 8); + + assign(test_msg_.signature.data[9], 9); + + assign(test_msg_.signature.data[10], 10); + + assign(test_msg_.signature.data[11], 11); + + assign(test_msg_.signature.data[12], 12); + + assign(test_msg_.signature.data[13], 13); + + assign(test_msg_.signature.data[14], 14); + + assign(test_msg_.signature.data[15], 15); + + assign(test_msg_.signature.data[16], 16); + + assign(test_msg_.signature.data[17], 17); + + assign(test_msg_.signature.data[18], 18); + + assign(test_msg_.signature.data[19], 19); + + assign(test_msg_.signature.data[20], 20); + + assign(test_msg_.signature.data[21], 21); + + assign(test_msg_.signature.data[22], 22); + + assign(test_msg_.signature.data[23], 23); + + assign(test_msg_.signature.data[24], 24); + + assign(test_msg_.signature.data[25], 25); + + assign(test_msg_.signature.data[26], 26); + + assign(test_msg_.signature.data[27], 27); + + assign(test_msg_.signature.data[28], 28); + + assign(test_msg_.signature.data[29], 29); + + assign(test_msg_.signature.data[30], 30); + + assign(test_msg_.signature.data[31], 31); + + assign(test_msg_.signature.data[32], 32); + + assign(test_msg_.signature.data[33], 33); + + assign(test_msg_.signature.data[34], 34); + + assign(test_msg_.signature.data[35], 35); + + assign(test_msg_.signature.data[36], 36); + + assign(test_msg_.signature.data[37], 37); + + assign(test_msg_.signature.data[38], 38); + + assign(test_msg_.signature.data[39], 39); + + assign(test_msg_.signature.data[40], 40); + + assign(test_msg_.signature.data[41], 41); + + assign(test_msg_.signature.data[42], 42); + + assign(test_msg_.signature.data[43], 43); + + assign(test_msg_.signature.data[44], 44); + + assign(test_msg_.signature.data[45], 45); + + assign(test_msg_.signature.data[46], 46); + + assign(test_msg_.signature.data[47], 47); + + assign(test_msg_.signature.data[48], 48); + + assign(test_msg_.signature.data[49], 49); + + assign(test_msg_.signature.data[50], 50); + + assign(test_msg_.signature.data[51], 51); + + assign(test_msg_.signature.data[52], 52); + + assign(test_msg_.signature.data[53], 53); + + assign(test_msg_.signature.data[54], 54); + + assign(test_msg_.signature.data[55], 55); + + assign(test_msg_.signature.data[56], 56); + + assign(test_msg_.signature.data[57], 57); + + assign(test_msg_.signature.data[58], 58); + + assign(test_msg_.signature.data[59], 59); + + assign(test_msg_.signature.data[60], 60); + + assign(test_msg_.signature.data[61], 61); + + assign(test_msg_.signature.data[62], 62); + + assign(test_msg_.signature.data[63], 63); + + assign(test_msg_.signature.data[64], 64); + + assign(test_msg_.signature.data[65], 65); + + assign(test_msg_.signature.data[66], 66); + + assign(test_msg_.signature.data[67], 67); + + assign(test_msg_.signature.data[68], 68); + + assign(test_msg_.signature.data[69], 69); + + assign(test_msg_.signature.data[70], 70); + + assign(test_msg_.signature.data[71], 71); + assign(test_msg_.signature.len, 72); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_certificate_chain_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_certificate_chain_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgCertificateChain, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_certificate_chain_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgCertificateChain); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->certificate_chain, + sizeof(msg->certificate_chain)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_certificate_chain_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.certificate_chain, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgCertificateChain); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xE0E3; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 144; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_certificate_chain_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_certificate_chain_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_certificate_chain_t &lesser, + const sbp_msg_certificate_chain_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_certificate_chain_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_certificate_chain_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_certificate_chain_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_certificate_chain_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgCertificateChain, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgCertificateChain, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgCertificateChain, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgCertificateChain, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_signing_MsgCertificateChain0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_certificate_chain_t test_msg_{}; + uint8_t encoded_frame_[144 + 8] = { 85, 9, 12, 66, 0, 144, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, @@ -86,751 +567,1339 @@ TEST_F(Test_auto_check_sbp_signing_MsgCertificateChain0, Test) { 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 227, 224, }; + uint8_t encoded_payload_[144] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, + 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 232, 7, 3, 30, 12, 34, 59, 21, 205, 91, 7, 72, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, + }; +}; + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_certificate_chain_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgCertificateChain, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[144]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_certificate_chain_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 144); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 144), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgCertificateChain, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 144); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 144), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[144]; + + EXPECT_EQ(sbp_msg_certificate_chain_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 144), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[144]; + + for (uint8_t i = 0; i < 144; i++) { + EXPECT_EQ( + sbp_msg_certificate_chain_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_certificate_chain_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 144); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgCertificateChain, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 144); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_t msg{}; + + EXPECT_EQ(sbp_msg_certificate_chain_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_certificate_chain_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - sbp_msg_certificate_chain_t test_msg{}; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.corrections_certificate[0] = 20; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.corrections_certificate[1] = 21; + EXPECT_EQ(sbp_msg_certificate_chain_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.corrections_certificate[2] = 22; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.corrections_certificate[3] = 23; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.corrections_certificate[4] = 24; + EXPECT_EQ(sbp_message_send(&state, SbpMsgCertificateChain, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.corrections_certificate[5] = 25; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, Comparison) { + auto info = get_test_msg_info(); - test_msg.corrections_certificate[6] = 26; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[0], + greater.corrections_certificate[0]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[7] = 27; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[1], + greater.corrections_certificate[1]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[8] = 28; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[2], + greater.corrections_certificate[2]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[9] = 29; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[3], + greater.corrections_certificate[3]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[10] = 10; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[4], + greater.corrections_certificate[4]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[11] = 11; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[5], + greater.corrections_certificate[5]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[12] = 12; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[6], + greater.corrections_certificate[6]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[13] = 13; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[7], + greater.corrections_certificate[7]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[14] = 14; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[8], + greater.corrections_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[15] = 15; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[9], + greater.corrections_certificate[9]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[16] = 16; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[10], + greater.corrections_certificate[10]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[17] = 17; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[11], + greater.corrections_certificate[11]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[18] = 18; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[12], + greater.corrections_certificate[12]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[19] = 19; - test_msg.expiration.day = 30; - test_msg.expiration.hours = 12; - test_msg.expiration.minutes = 34; - test_msg.expiration.month = 3; - test_msg.expiration.ns = 123456789; - test_msg.expiration.seconds = 59; - test_msg.expiration.year = 2024; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[13], + greater.corrections_certificate[13]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[0] = 10; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[14], + greater.corrections_certificate[14]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[1] = 11; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[15], + greater.corrections_certificate[15]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[2] = 12; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[16], + greater.corrections_certificate[16]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[3] = 13; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[17], + greater.corrections_certificate[17]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[4] = 14; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[18], + greater.corrections_certificate[18]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[5] = 15; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[19], + greater.corrections_certificate[19]); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.day, greater.expiration.day); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.hours, greater.expiration.hours); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.minutes, greater.expiration.minutes); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.month, greater.expiration.month); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.ns, greater.expiration.ns); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.seconds, greater.expiration.seconds); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.year, greater.expiration.year); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[6] = 16; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[0], + greater.intermediate_certificate[0]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[7] = 17; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[1], + greater.intermediate_certificate[1]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[8] = 18; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[2], + greater.intermediate_certificate[2]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[9] = 19; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[3], + greater.intermediate_certificate[3]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[10] = 0; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[4], + greater.intermediate_certificate[4]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[11] = 1; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[5], + greater.intermediate_certificate[5]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[12] = 2; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[6], + greater.intermediate_certificate[6]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[13] = 3; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[7], + greater.intermediate_certificate[7]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[14] = 4; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[8], + greater.intermediate_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[15] = 5; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[9], + greater.intermediate_certificate[9]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[16] = 6; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[10], + greater.intermediate_certificate[10]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[17] = 7; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[11], + greater.intermediate_certificate[11]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[18] = 8; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[12], + greater.intermediate_certificate[12]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[19] = 9; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[13], + greater.intermediate_certificate[13]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[0] = 0; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[14], + greater.intermediate_certificate[14]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[1] = 1; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[15], + greater.intermediate_certificate[15]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[2] = 2; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[16], + greater.intermediate_certificate[16]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[3] = 3; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[17], + greater.intermediate_certificate[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[18], + greater.intermediate_certificate[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[19], + greater.intermediate_certificate[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[0], + greater.root_certificate[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[1], + greater.root_certificate[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[2], + greater.root_certificate[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[3], + greater.root_certificate[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[4], + greater.root_certificate[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[5], + greater.root_certificate[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[6], + greater.root_certificate[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[7], + greater.root_certificate[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[8], + greater.root_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[4] = 4; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[9], + greater.root_certificate[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[10], + greater.root_certificate[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[11], + greater.root_certificate[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[12], + greater.root_certificate[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[13], + greater.root_certificate[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[14], + greater.root_certificate[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[15], + greater.root_certificate[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[16], + greater.root_certificate[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[17], + greater.root_certificate[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[18], + greater.root_certificate[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[19], + greater.root_certificate[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[0], greater.signature.data[0]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[5] = 5; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[1], greater.signature.data[1]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[6] = 6; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[2], greater.signature.data[2]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[7] = 7; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[3], greater.signature.data[3]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[8] = 8; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[4], greater.signature.data[4]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[9] = 9; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[5], greater.signature.data[5]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[10] = 10; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[6], greater.signature.data[6]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[11] = 11; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[7], greater.signature.data[7]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[12] = 12; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[8], greater.signature.data[8]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[13] = 13; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[9], greater.signature.data[9]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[14] = 14; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[10], greater.signature.data[10]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[15] = 15; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[11], greater.signature.data[11]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[16] = 16; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[12], greater.signature.data[12]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[17] = 17; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[13], greater.signature.data[13]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[18] = 18; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[14], greater.signature.data[14]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[19] = 19; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[15], greater.signature.data[15]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[0] = 0; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[16], greater.signature.data[16]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[1] = 1; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[17], greater.signature.data[17]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[2] = 2; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[18], greater.signature.data[18]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[3] = 3; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[19], greater.signature.data[19]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[4] = 4; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[20], greater.signature.data[20]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[5] = 5; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[21], greater.signature.data[21]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[6] = 6; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[22], greater.signature.data[22]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[7] = 7; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[23], greater.signature.data[23]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[8] = 8; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[24], greater.signature.data[24]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[9] = 9; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[25], greater.signature.data[25]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[10] = 10; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[26], greater.signature.data[26]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[11] = 11; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[27], greater.signature.data[27]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[12] = 12; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[28], greater.signature.data[28]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[13] = 13; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[29], greater.signature.data[29]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[14] = 14; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[30], greater.signature.data[30]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[15] = 15; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[31], greater.signature.data[31]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[16] = 16; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[32], greater.signature.data[32]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[17] = 17; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[33], greater.signature.data[33]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[18] = 18; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[34], greater.signature.data[34]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[19] = 19; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[35], greater.signature.data[35]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[20] = 20; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[36], greater.signature.data[36]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[21] = 21; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[37], greater.signature.data[37]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[22] = 22; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[38], greater.signature.data[38]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[23] = 23; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[39], greater.signature.data[39]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[24] = 24; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[40], greater.signature.data[40]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[25] = 25; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[41], greater.signature.data[41]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[26] = 26; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[42], greater.signature.data[42]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[27] = 27; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[43], greater.signature.data[43]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[28] = 28; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[44], greater.signature.data[44]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[29] = 29; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[45], greater.signature.data[45]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[30] = 30; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[46], greater.signature.data[46]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[31] = 31; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[47], greater.signature.data[47]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[32] = 32; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[48], greater.signature.data[48]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[33] = 33; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[49], greater.signature.data[49]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[34] = 34; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[50], greater.signature.data[50]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[35] = 35; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[51], greater.signature.data[51]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[36] = 36; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[52], greater.signature.data[52]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[37] = 37; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[53], greater.signature.data[53]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[38] = 38; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[54], greater.signature.data[54]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[39] = 39; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[55], greater.signature.data[55]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[40] = 40; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[56], greater.signature.data[56]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[41] = 41; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[57], greater.signature.data[57]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[42] = 42; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[58], greater.signature.data[58]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[43] = 43; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[59], greater.signature.data[59]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[44] = 44; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[60], greater.signature.data[60]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[45] = 45; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[61], greater.signature.data[61]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[46] = 46; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[62], greater.signature.data[62]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[47] = 47; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[63], greater.signature.data[63]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[48] = 48; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[64], greater.signature.data[64]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[49] = 49; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[65], greater.signature.data[65]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[50] = 50; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[66], greater.signature.data[66]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[51] = 51; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[67], greater.signature.data[67]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[52] = 52; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[68], greater.signature.data[68]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[53] = 53; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[69], greater.signature.data[69]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[54] = 54; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[70], greater.signature.data[70]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[55] = 55; + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[71], greater.signature.data[71]); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_t lesser = info.test_msg; + sbp_msg_certificate_chain_t greater = info.test_msg; + make_lesser_greater(lesser.signature.len, greater.signature.len); + comparison_tests(lesser, greater); + } +} - test_msg.signature.data[56] = 56; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgCertificateChain); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_CERTIFICATE_CHAIN"); +} - test_msg.signature.data[57] = 57; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature.data[58] = 58; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.signature.data[59] = 59; + const sbp_msg_certificate_chain_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_certificate_chain_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - test_msg.signature.data[60] = 60; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.signature.data[61] = 61; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature.data[62] = 62; + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.certificate_chain, info.test_msg); - test_msg.signature.data[63] = 63; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.certificate_chain, info.test_msg); +} - test_msg.signature.data[64] = 64; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.signature.data[65] = 65; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature.data[66] = 66; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature.data[67] = 67; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.signature.data[68] = 68; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[144]; + uint8_t n_written; - test_msg.signature.data[69] = 69; + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 144); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 144), 0); +} - test_msg.signature.data[70] = 70; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 144); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signature.data[71] = 71; - test_msg.signature.len = 72; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.corrections_certificate[0], 20) - << "incorrect value for last_msg_.corrections_certificate[0], expected " - "20, is " - << last_msg_.corrections_certificate[0]; - EXPECT_EQ(last_msg_.corrections_certificate[1], 21) - << "incorrect value for last_msg_.corrections_certificate[1], expected " - "21, is " - << last_msg_.corrections_certificate[1]; - EXPECT_EQ(last_msg_.corrections_certificate[2], 22) - << "incorrect value for last_msg_.corrections_certificate[2], expected " - "22, is " - << last_msg_.corrections_certificate[2]; - EXPECT_EQ(last_msg_.corrections_certificate[3], 23) - << "incorrect value for last_msg_.corrections_certificate[3], expected " - "23, is " - << last_msg_.corrections_certificate[3]; - EXPECT_EQ(last_msg_.corrections_certificate[4], 24) - << "incorrect value for last_msg_.corrections_certificate[4], expected " - "24, is " - << last_msg_.corrections_certificate[4]; - EXPECT_EQ(last_msg_.corrections_certificate[5], 25) - << "incorrect value for last_msg_.corrections_certificate[5], expected " - "25, is " - << last_msg_.corrections_certificate[5]; - EXPECT_EQ(last_msg_.corrections_certificate[6], 26) - << "incorrect value for last_msg_.corrections_certificate[6], expected " - "26, is " - << last_msg_.corrections_certificate[6]; - EXPECT_EQ(last_msg_.corrections_certificate[7], 27) - << "incorrect value for last_msg_.corrections_certificate[7], expected " - "27, is " - << last_msg_.corrections_certificate[7]; - EXPECT_EQ(last_msg_.corrections_certificate[8], 28) - << "incorrect value for last_msg_.corrections_certificate[8], expected " - "28, is " - << last_msg_.corrections_certificate[8]; - EXPECT_EQ(last_msg_.corrections_certificate[9], 29) - << "incorrect value for last_msg_.corrections_certificate[9], expected " - "29, is " - << last_msg_.corrections_certificate[9]; - EXPECT_EQ(last_msg_.corrections_certificate[10], 10) - << "incorrect value for last_msg_.corrections_certificate[10], expected " - "10, is " - << last_msg_.corrections_certificate[10]; - EXPECT_EQ(last_msg_.corrections_certificate[11], 11) - << "incorrect value for last_msg_.corrections_certificate[11], expected " - "11, is " - << last_msg_.corrections_certificate[11]; - EXPECT_EQ(last_msg_.corrections_certificate[12], 12) - << "incorrect value for last_msg_.corrections_certificate[12], expected " - "12, is " - << last_msg_.corrections_certificate[12]; - EXPECT_EQ(last_msg_.corrections_certificate[13], 13) - << "incorrect value for last_msg_.corrections_certificate[13], expected " - "13, is " - << last_msg_.corrections_certificate[13]; - EXPECT_EQ(last_msg_.corrections_certificate[14], 14) - << "incorrect value for last_msg_.corrections_certificate[14], expected " - "14, is " - << last_msg_.corrections_certificate[14]; - EXPECT_EQ(last_msg_.corrections_certificate[15], 15) - << "incorrect value for last_msg_.corrections_certificate[15], expected " - "15, is " - << last_msg_.corrections_certificate[15]; - EXPECT_EQ(last_msg_.corrections_certificate[16], 16) - << "incorrect value for last_msg_.corrections_certificate[16], expected " - "16, is " - << last_msg_.corrections_certificate[16]; - EXPECT_EQ(last_msg_.corrections_certificate[17], 17) - << "incorrect value for last_msg_.corrections_certificate[17], expected " - "17, is " - << last_msg_.corrections_certificate[17]; - EXPECT_EQ(last_msg_.corrections_certificate[18], 18) - << "incorrect value for last_msg_.corrections_certificate[18], expected " - "18, is " - << last_msg_.corrections_certificate[18]; - EXPECT_EQ(last_msg_.corrections_certificate[19], 19) - << "incorrect value for last_msg_.corrections_certificate[19], expected " - "19, is " - << last_msg_.corrections_certificate[19]; - EXPECT_EQ(last_msg_.expiration.day, 30) - << "incorrect value for last_msg_.expiration.day, expected 30, is " - << last_msg_.expiration.day; - EXPECT_EQ(last_msg_.expiration.hours, 12) - << "incorrect value for last_msg_.expiration.hours, expected 12, is " - << last_msg_.expiration.hours; - EXPECT_EQ(last_msg_.expiration.minutes, 34) - << "incorrect value for last_msg_.expiration.minutes, expected 34, is " - << last_msg_.expiration.minutes; - EXPECT_EQ(last_msg_.expiration.month, 3) - << "incorrect value for last_msg_.expiration.month, expected 3, is " - << last_msg_.expiration.month; - EXPECT_EQ(last_msg_.expiration.ns, 123456789) - << "incorrect value for last_msg_.expiration.ns, expected 123456789, is " - << last_msg_.expiration.ns; - EXPECT_EQ(last_msg_.expiration.seconds, 59) - << "incorrect value for last_msg_.expiration.seconds, expected 59, is " - << last_msg_.expiration.seconds; - EXPECT_EQ(last_msg_.expiration.year, 2024) - << "incorrect value for last_msg_.expiration.year, expected 2024, is " - << last_msg_.expiration.year; - EXPECT_EQ(last_msg_.intermediate_certificate[0], 10) - << "incorrect value for last_msg_.intermediate_certificate[0], expected " - "10, is " - << last_msg_.intermediate_certificate[0]; - EXPECT_EQ(last_msg_.intermediate_certificate[1], 11) - << "incorrect value for last_msg_.intermediate_certificate[1], expected " - "11, is " - << last_msg_.intermediate_certificate[1]; - EXPECT_EQ(last_msg_.intermediate_certificate[2], 12) - << "incorrect value for last_msg_.intermediate_certificate[2], expected " - "12, is " - << last_msg_.intermediate_certificate[2]; - EXPECT_EQ(last_msg_.intermediate_certificate[3], 13) - << "incorrect value for last_msg_.intermediate_certificate[3], expected " - "13, is " - << last_msg_.intermediate_certificate[3]; - EXPECT_EQ(last_msg_.intermediate_certificate[4], 14) - << "incorrect value for last_msg_.intermediate_certificate[4], expected " - "14, is " - << last_msg_.intermediate_certificate[4]; - EXPECT_EQ(last_msg_.intermediate_certificate[5], 15) - << "incorrect value for last_msg_.intermediate_certificate[5], expected " - "15, is " - << last_msg_.intermediate_certificate[5]; - EXPECT_EQ(last_msg_.intermediate_certificate[6], 16) - << "incorrect value for last_msg_.intermediate_certificate[6], expected " - "16, is " - << last_msg_.intermediate_certificate[6]; - EXPECT_EQ(last_msg_.intermediate_certificate[7], 17) - << "incorrect value for last_msg_.intermediate_certificate[7], expected " - "17, is " - << last_msg_.intermediate_certificate[7]; - EXPECT_EQ(last_msg_.intermediate_certificate[8], 18) - << "incorrect value for last_msg_.intermediate_certificate[8], expected " - "18, is " - << last_msg_.intermediate_certificate[8]; - EXPECT_EQ(last_msg_.intermediate_certificate[9], 19) - << "incorrect value for last_msg_.intermediate_certificate[9], expected " - "19, is " - << last_msg_.intermediate_certificate[9]; - EXPECT_EQ(last_msg_.intermediate_certificate[10], 0) - << "incorrect value for last_msg_.intermediate_certificate[10], expected " - "0, is " - << last_msg_.intermediate_certificate[10]; - EXPECT_EQ(last_msg_.intermediate_certificate[11], 1) - << "incorrect value for last_msg_.intermediate_certificate[11], expected " - "1, is " - << last_msg_.intermediate_certificate[11]; - EXPECT_EQ(last_msg_.intermediate_certificate[12], 2) - << "incorrect value for last_msg_.intermediate_certificate[12], expected " - "2, is " - << last_msg_.intermediate_certificate[12]; - EXPECT_EQ(last_msg_.intermediate_certificate[13], 3) - << "incorrect value for last_msg_.intermediate_certificate[13], expected " - "3, is " - << last_msg_.intermediate_certificate[13]; - EXPECT_EQ(last_msg_.intermediate_certificate[14], 4) - << "incorrect value for last_msg_.intermediate_certificate[14], expected " - "4, is " - << last_msg_.intermediate_certificate[14]; - EXPECT_EQ(last_msg_.intermediate_certificate[15], 5) - << "incorrect value for last_msg_.intermediate_certificate[15], expected " - "5, is " - << last_msg_.intermediate_certificate[15]; - EXPECT_EQ(last_msg_.intermediate_certificate[16], 6) - << "incorrect value for last_msg_.intermediate_certificate[16], expected " - "6, is " - << last_msg_.intermediate_certificate[16]; - EXPECT_EQ(last_msg_.intermediate_certificate[17], 7) - << "incorrect value for last_msg_.intermediate_certificate[17], expected " - "7, is " - << last_msg_.intermediate_certificate[17]; - EXPECT_EQ(last_msg_.intermediate_certificate[18], 8) - << "incorrect value for last_msg_.intermediate_certificate[18], expected " - "8, is " - << last_msg_.intermediate_certificate[18]; - EXPECT_EQ(last_msg_.intermediate_certificate[19], 9) - << "incorrect value for last_msg_.intermediate_certificate[19], expected " - "9, is " - << last_msg_.intermediate_certificate[19]; - EXPECT_EQ(last_msg_.root_certificate[0], 0) - << "incorrect value for last_msg_.root_certificate[0], expected 0, is " - << last_msg_.root_certificate[0]; - EXPECT_EQ(last_msg_.root_certificate[1], 1) - << "incorrect value for last_msg_.root_certificate[1], expected 1, is " - << last_msg_.root_certificate[1]; - EXPECT_EQ(last_msg_.root_certificate[2], 2) - << "incorrect value for last_msg_.root_certificate[2], expected 2, is " - << last_msg_.root_certificate[2]; - EXPECT_EQ(last_msg_.root_certificate[3], 3) - << "incorrect value for last_msg_.root_certificate[3], expected 3, is " - << last_msg_.root_certificate[3]; - EXPECT_EQ(last_msg_.root_certificate[4], 4) - << "incorrect value for last_msg_.root_certificate[4], expected 4, is " - << last_msg_.root_certificate[4]; - EXPECT_EQ(last_msg_.root_certificate[5], 5) - << "incorrect value for last_msg_.root_certificate[5], expected 5, is " - << last_msg_.root_certificate[5]; - EXPECT_EQ(last_msg_.root_certificate[6], 6) - << "incorrect value for last_msg_.root_certificate[6], expected 6, is " - << last_msg_.root_certificate[6]; - EXPECT_EQ(last_msg_.root_certificate[7], 7) - << "incorrect value for last_msg_.root_certificate[7], expected 7, is " - << last_msg_.root_certificate[7]; - EXPECT_EQ(last_msg_.root_certificate[8], 8) - << "incorrect value for last_msg_.root_certificate[8], expected 8, is " - << last_msg_.root_certificate[8]; - EXPECT_EQ(last_msg_.root_certificate[9], 9) - << "incorrect value for last_msg_.root_certificate[9], expected 9, is " - << last_msg_.root_certificate[9]; - EXPECT_EQ(last_msg_.root_certificate[10], 10) - << "incorrect value for last_msg_.root_certificate[10], expected 10, is " - << last_msg_.root_certificate[10]; - EXPECT_EQ(last_msg_.root_certificate[11], 11) - << "incorrect value for last_msg_.root_certificate[11], expected 11, is " - << last_msg_.root_certificate[11]; - EXPECT_EQ(last_msg_.root_certificate[12], 12) - << "incorrect value for last_msg_.root_certificate[12], expected 12, is " - << last_msg_.root_certificate[12]; - EXPECT_EQ(last_msg_.root_certificate[13], 13) - << "incorrect value for last_msg_.root_certificate[13], expected 13, is " - << last_msg_.root_certificate[13]; - EXPECT_EQ(last_msg_.root_certificate[14], 14) - << "incorrect value for last_msg_.root_certificate[14], expected 14, is " - << last_msg_.root_certificate[14]; - EXPECT_EQ(last_msg_.root_certificate[15], 15) - << "incorrect value for last_msg_.root_certificate[15], expected 15, is " - << last_msg_.root_certificate[15]; - EXPECT_EQ(last_msg_.root_certificate[16], 16) - << "incorrect value for last_msg_.root_certificate[16], expected 16, is " - << last_msg_.root_certificate[16]; - EXPECT_EQ(last_msg_.root_certificate[17], 17) - << "incorrect value for last_msg_.root_certificate[17], expected 17, is " - << last_msg_.root_certificate[17]; - EXPECT_EQ(last_msg_.root_certificate[18], 18) - << "incorrect value for last_msg_.root_certificate[18], expected 18, is " - << last_msg_.root_certificate[18]; - EXPECT_EQ(last_msg_.root_certificate[19], 19) - << "incorrect value for last_msg_.root_certificate[19], expected 19, is " - << last_msg_.root_certificate[19]; - EXPECT_EQ(last_msg_.signature.data[0], 0) - << "incorrect value for last_msg_.signature.data[0], expected 0, is " - << last_msg_.signature.data[0]; - EXPECT_EQ(last_msg_.signature.data[1], 1) - << "incorrect value for last_msg_.signature.data[1], expected 1, is " - << last_msg_.signature.data[1]; - EXPECT_EQ(last_msg_.signature.data[2], 2) - << "incorrect value for last_msg_.signature.data[2], expected 2, is " - << last_msg_.signature.data[2]; - EXPECT_EQ(last_msg_.signature.data[3], 3) - << "incorrect value for last_msg_.signature.data[3], expected 3, is " - << last_msg_.signature.data[3]; - EXPECT_EQ(last_msg_.signature.data[4], 4) - << "incorrect value for last_msg_.signature.data[4], expected 4, is " - << last_msg_.signature.data[4]; - EXPECT_EQ(last_msg_.signature.data[5], 5) - << "incorrect value for last_msg_.signature.data[5], expected 5, is " - << last_msg_.signature.data[5]; - EXPECT_EQ(last_msg_.signature.data[6], 6) - << "incorrect value for last_msg_.signature.data[6], expected 6, is " - << last_msg_.signature.data[6]; - EXPECT_EQ(last_msg_.signature.data[7], 7) - << "incorrect value for last_msg_.signature.data[7], expected 7, is " - << last_msg_.signature.data[7]; - EXPECT_EQ(last_msg_.signature.data[8], 8) - << "incorrect value for last_msg_.signature.data[8], expected 8, is " - << last_msg_.signature.data[8]; - EXPECT_EQ(last_msg_.signature.data[9], 9) - << "incorrect value for last_msg_.signature.data[9], expected 9, is " - << last_msg_.signature.data[9]; - EXPECT_EQ(last_msg_.signature.data[10], 10) - << "incorrect value for last_msg_.signature.data[10], expected 10, is " - << last_msg_.signature.data[10]; - EXPECT_EQ(last_msg_.signature.data[11], 11) - << "incorrect value for last_msg_.signature.data[11], expected 11, is " - << last_msg_.signature.data[11]; - EXPECT_EQ(last_msg_.signature.data[12], 12) - << "incorrect value for last_msg_.signature.data[12], expected 12, is " - << last_msg_.signature.data[12]; - EXPECT_EQ(last_msg_.signature.data[13], 13) - << "incorrect value for last_msg_.signature.data[13], expected 13, is " - << last_msg_.signature.data[13]; - EXPECT_EQ(last_msg_.signature.data[14], 14) - << "incorrect value for last_msg_.signature.data[14], expected 14, is " - << last_msg_.signature.data[14]; - EXPECT_EQ(last_msg_.signature.data[15], 15) - << "incorrect value for last_msg_.signature.data[15], expected 15, is " - << last_msg_.signature.data[15]; - EXPECT_EQ(last_msg_.signature.data[16], 16) - << "incorrect value for last_msg_.signature.data[16], expected 16, is " - << last_msg_.signature.data[16]; - EXPECT_EQ(last_msg_.signature.data[17], 17) - << "incorrect value for last_msg_.signature.data[17], expected 17, is " - << last_msg_.signature.data[17]; - EXPECT_EQ(last_msg_.signature.data[18], 18) - << "incorrect value for last_msg_.signature.data[18], expected 18, is " - << last_msg_.signature.data[18]; - EXPECT_EQ(last_msg_.signature.data[19], 19) - << "incorrect value for last_msg_.signature.data[19], expected 19, is " - << last_msg_.signature.data[19]; - EXPECT_EQ(last_msg_.signature.data[20], 20) - << "incorrect value for last_msg_.signature.data[20], expected 20, is " - << last_msg_.signature.data[20]; - EXPECT_EQ(last_msg_.signature.data[21], 21) - << "incorrect value for last_msg_.signature.data[21], expected 21, is " - << last_msg_.signature.data[21]; - EXPECT_EQ(last_msg_.signature.data[22], 22) - << "incorrect value for last_msg_.signature.data[22], expected 22, is " - << last_msg_.signature.data[22]; - EXPECT_EQ(last_msg_.signature.data[23], 23) - << "incorrect value for last_msg_.signature.data[23], expected 23, is " - << last_msg_.signature.data[23]; - EXPECT_EQ(last_msg_.signature.data[24], 24) - << "incorrect value for last_msg_.signature.data[24], expected 24, is " - << last_msg_.signature.data[24]; - EXPECT_EQ(last_msg_.signature.data[25], 25) - << "incorrect value for last_msg_.signature.data[25], expected 25, is " - << last_msg_.signature.data[25]; - EXPECT_EQ(last_msg_.signature.data[26], 26) - << "incorrect value for last_msg_.signature.data[26], expected 26, is " - << last_msg_.signature.data[26]; - EXPECT_EQ(last_msg_.signature.data[27], 27) - << "incorrect value for last_msg_.signature.data[27], expected 27, is " - << last_msg_.signature.data[27]; - EXPECT_EQ(last_msg_.signature.data[28], 28) - << "incorrect value for last_msg_.signature.data[28], expected 28, is " - << last_msg_.signature.data[28]; - EXPECT_EQ(last_msg_.signature.data[29], 29) - << "incorrect value for last_msg_.signature.data[29], expected 29, is " - << last_msg_.signature.data[29]; - EXPECT_EQ(last_msg_.signature.data[30], 30) - << "incorrect value for last_msg_.signature.data[30], expected 30, is " - << last_msg_.signature.data[30]; - EXPECT_EQ(last_msg_.signature.data[31], 31) - << "incorrect value for last_msg_.signature.data[31], expected 31, is " - << last_msg_.signature.data[31]; - EXPECT_EQ(last_msg_.signature.data[32], 32) - << "incorrect value for last_msg_.signature.data[32], expected 32, is " - << last_msg_.signature.data[32]; - EXPECT_EQ(last_msg_.signature.data[33], 33) - << "incorrect value for last_msg_.signature.data[33], expected 33, is " - << last_msg_.signature.data[33]; - EXPECT_EQ(last_msg_.signature.data[34], 34) - << "incorrect value for last_msg_.signature.data[34], expected 34, is " - << last_msg_.signature.data[34]; - EXPECT_EQ(last_msg_.signature.data[35], 35) - << "incorrect value for last_msg_.signature.data[35], expected 35, is " - << last_msg_.signature.data[35]; - EXPECT_EQ(last_msg_.signature.data[36], 36) - << "incorrect value for last_msg_.signature.data[36], expected 36, is " - << last_msg_.signature.data[36]; - EXPECT_EQ(last_msg_.signature.data[37], 37) - << "incorrect value for last_msg_.signature.data[37], expected 37, is " - << last_msg_.signature.data[37]; - EXPECT_EQ(last_msg_.signature.data[38], 38) - << "incorrect value for last_msg_.signature.data[38], expected 38, is " - << last_msg_.signature.data[38]; - EXPECT_EQ(last_msg_.signature.data[39], 39) - << "incorrect value for last_msg_.signature.data[39], expected 39, is " - << last_msg_.signature.data[39]; - EXPECT_EQ(last_msg_.signature.data[40], 40) - << "incorrect value for last_msg_.signature.data[40], expected 40, is " - << last_msg_.signature.data[40]; - EXPECT_EQ(last_msg_.signature.data[41], 41) - << "incorrect value for last_msg_.signature.data[41], expected 41, is " - << last_msg_.signature.data[41]; - EXPECT_EQ(last_msg_.signature.data[42], 42) - << "incorrect value for last_msg_.signature.data[42], expected 42, is " - << last_msg_.signature.data[42]; - EXPECT_EQ(last_msg_.signature.data[43], 43) - << "incorrect value for last_msg_.signature.data[43], expected 43, is " - << last_msg_.signature.data[43]; - EXPECT_EQ(last_msg_.signature.data[44], 44) - << "incorrect value for last_msg_.signature.data[44], expected 44, is " - << last_msg_.signature.data[44]; - EXPECT_EQ(last_msg_.signature.data[45], 45) - << "incorrect value for last_msg_.signature.data[45], expected 45, is " - << last_msg_.signature.data[45]; - EXPECT_EQ(last_msg_.signature.data[46], 46) - << "incorrect value for last_msg_.signature.data[46], expected 46, is " - << last_msg_.signature.data[46]; - EXPECT_EQ(last_msg_.signature.data[47], 47) - << "incorrect value for last_msg_.signature.data[47], expected 47, is " - << last_msg_.signature.data[47]; - EXPECT_EQ(last_msg_.signature.data[48], 48) - << "incorrect value for last_msg_.signature.data[48], expected 48, is " - << last_msg_.signature.data[48]; - EXPECT_EQ(last_msg_.signature.data[49], 49) - << "incorrect value for last_msg_.signature.data[49], expected 49, is " - << last_msg_.signature.data[49]; - EXPECT_EQ(last_msg_.signature.data[50], 50) - << "incorrect value for last_msg_.signature.data[50], expected 50, is " - << last_msg_.signature.data[50]; - EXPECT_EQ(last_msg_.signature.data[51], 51) - << "incorrect value for last_msg_.signature.data[51], expected 51, is " - << last_msg_.signature.data[51]; - EXPECT_EQ(last_msg_.signature.data[52], 52) - << "incorrect value for last_msg_.signature.data[52], expected 52, is " - << last_msg_.signature.data[52]; - EXPECT_EQ(last_msg_.signature.data[53], 53) - << "incorrect value for last_msg_.signature.data[53], expected 53, is " - << last_msg_.signature.data[53]; - EXPECT_EQ(last_msg_.signature.data[54], 54) - << "incorrect value for last_msg_.signature.data[54], expected 54, is " - << last_msg_.signature.data[54]; - EXPECT_EQ(last_msg_.signature.data[55], 55) - << "incorrect value for last_msg_.signature.data[55], expected 55, is " - << last_msg_.signature.data[55]; - EXPECT_EQ(last_msg_.signature.data[56], 56) - << "incorrect value for last_msg_.signature.data[56], expected 56, is " - << last_msg_.signature.data[56]; - EXPECT_EQ(last_msg_.signature.data[57], 57) - << "incorrect value for last_msg_.signature.data[57], expected 57, is " - << last_msg_.signature.data[57]; - EXPECT_EQ(last_msg_.signature.data[58], 58) - << "incorrect value for last_msg_.signature.data[58], expected 58, is " - << last_msg_.signature.data[58]; - EXPECT_EQ(last_msg_.signature.data[59], 59) - << "incorrect value for last_msg_.signature.data[59], expected 59, is " - << last_msg_.signature.data[59]; - EXPECT_EQ(last_msg_.signature.data[60], 60) - << "incorrect value for last_msg_.signature.data[60], expected 60, is " - << last_msg_.signature.data[60]; - EXPECT_EQ(last_msg_.signature.data[61], 61) - << "incorrect value for last_msg_.signature.data[61], expected 61, is " - << last_msg_.signature.data[61]; - EXPECT_EQ(last_msg_.signature.data[62], 62) - << "incorrect value for last_msg_.signature.data[62], expected 62, is " - << last_msg_.signature.data[62]; - EXPECT_EQ(last_msg_.signature.data[63], 63) - << "incorrect value for last_msg_.signature.data[63], expected 63, is " - << last_msg_.signature.data[63]; - EXPECT_EQ(last_msg_.signature.data[64], 64) - << "incorrect value for last_msg_.signature.data[64], expected 64, is " - << last_msg_.signature.data[64]; - EXPECT_EQ(last_msg_.signature.data[65], 65) - << "incorrect value for last_msg_.signature.data[65], expected 65, is " - << last_msg_.signature.data[65]; - EXPECT_EQ(last_msg_.signature.data[66], 66) - << "incorrect value for last_msg_.signature.data[66], expected 66, is " - << last_msg_.signature.data[66]; - EXPECT_EQ(last_msg_.signature.data[67], 67) - << "incorrect value for last_msg_.signature.data[67], expected 67, is " - << last_msg_.signature.data[67]; - EXPECT_EQ(last_msg_.signature.data[68], 68) - << "incorrect value for last_msg_.signature.data[68], expected 68, is " - << last_msg_.signature.data[68]; - EXPECT_EQ(last_msg_.signature.data[69], 69) - << "incorrect value for last_msg_.signature.data[69], expected 69, is " - << last_msg_.signature.data[69]; - EXPECT_EQ(last_msg_.signature.data[70], 70) - << "incorrect value for last_msg_.signature.data[70], expected 70, is " - << last_msg_.signature.data[70]; - EXPECT_EQ(last_msg_.signature.data[71], 71) - << "incorrect value for last_msg_.signature.data[71], expected 71, is " - << last_msg_.signature.data[71]; - EXPECT_EQ(last_msg_.signature.len, 72) - << "incorrect value for last_msg_.signature.len, expected 72, is " - << last_msg_.signature.len; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgCertificateChain, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChain0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgCertificateChain, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgCertificateChainDep.cc b/c/test/cpp/auto_check_sbp_signing_MsgCertificateChainDep.cc index d35bc09dad..dd11111aec 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgCertificateChainDep.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgCertificateChainDep.cc @@ -16,66 +16,532 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgCertificateChainDep0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgCertificateChainDep0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgCertificateChainDep0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgCertificateChainDep0() { + assign(test_msg_.corrections_certificate[0], 20); + + assign(test_msg_.corrections_certificate[1], 21); + + assign(test_msg_.corrections_certificate[2], 22); + + assign(test_msg_.corrections_certificate[3], 23); + + assign(test_msg_.corrections_certificate[4], 24); + + assign(test_msg_.corrections_certificate[5], 25); + + assign(test_msg_.corrections_certificate[6], 26); + + assign(test_msg_.corrections_certificate[7], 27); + + assign(test_msg_.corrections_certificate[8], 28); + + assign(test_msg_.corrections_certificate[9], 29); + + assign(test_msg_.corrections_certificate[10], 10); + + assign(test_msg_.corrections_certificate[11], 11); + + assign(test_msg_.corrections_certificate[12], 12); + + assign(test_msg_.corrections_certificate[13], 13); + + assign(test_msg_.corrections_certificate[14], 14); + + assign(test_msg_.corrections_certificate[15], 15); + + assign(test_msg_.corrections_certificate[16], 16); + + assign(test_msg_.corrections_certificate[17], 17); + + assign(test_msg_.corrections_certificate[18], 18); + + assign(test_msg_.corrections_certificate[19], 19); + assign(test_msg_.expiration.day, 30); + assign(test_msg_.expiration.hours, 12); + assign(test_msg_.expiration.minutes, 34); + assign(test_msg_.expiration.month, 3); + assign(test_msg_.expiration.ns, 123456789); + assign(test_msg_.expiration.seconds, 59); + assign(test_msg_.expiration.year, 2024); + + assign(test_msg_.intermediate_certificate[0], 10); + + assign(test_msg_.intermediate_certificate[1], 11); + + assign(test_msg_.intermediate_certificate[2], 12); + + assign(test_msg_.intermediate_certificate[3], 13); + + assign(test_msg_.intermediate_certificate[4], 14); + + assign(test_msg_.intermediate_certificate[5], 15); + + assign(test_msg_.intermediate_certificate[6], 16); + + assign(test_msg_.intermediate_certificate[7], 17); + + assign(test_msg_.intermediate_certificate[8], 18); + + assign(test_msg_.intermediate_certificate[9], 19); + + assign(test_msg_.intermediate_certificate[10], 0); + + assign(test_msg_.intermediate_certificate[11], 1); + + assign(test_msg_.intermediate_certificate[12], 2); + + assign(test_msg_.intermediate_certificate[13], 3); + + assign(test_msg_.intermediate_certificate[14], 4); + + assign(test_msg_.intermediate_certificate[15], 5); + + assign(test_msg_.intermediate_certificate[16], 6); + + assign(test_msg_.intermediate_certificate[17], 7); + + assign(test_msg_.intermediate_certificate[18], 8); + + assign(test_msg_.intermediate_certificate[19], 9); + + assign(test_msg_.root_certificate[0], 0); + + assign(test_msg_.root_certificate[1], 1); + + assign(test_msg_.root_certificate[2], 2); + + assign(test_msg_.root_certificate[3], 3); + + assign(test_msg_.root_certificate[4], 4); + + assign(test_msg_.root_certificate[5], 5); + + assign(test_msg_.root_certificate[6], 6); + + assign(test_msg_.root_certificate[7], 7); + + assign(test_msg_.root_certificate[8], 8); + + assign(test_msg_.root_certificate[9], 9); + + assign(test_msg_.root_certificate[10], 10); + + assign(test_msg_.root_certificate[11], 11); + + assign(test_msg_.root_certificate[12], 12); + + assign(test_msg_.root_certificate[13], 13); + + assign(test_msg_.root_certificate[14], 14); + + assign(test_msg_.root_certificate[15], 15); + + assign(test_msg_.root_certificate[16], 16); + + assign(test_msg_.root_certificate[17], 17); + + assign(test_msg_.root_certificate[18], 18); + + assign(test_msg_.root_certificate[19], 19); + + assign(test_msg_.signature[0], 0); + + assign(test_msg_.signature[1], 1); + + assign(test_msg_.signature[2], 2); + + assign(test_msg_.signature[3], 3); + + assign(test_msg_.signature[4], 4); + + assign(test_msg_.signature[5], 5); + + assign(test_msg_.signature[6], 6); + + assign(test_msg_.signature[7], 7); + + assign(test_msg_.signature[8], 0); + + assign(test_msg_.signature[9], 1); + + assign(test_msg_.signature[10], 2); + + assign(test_msg_.signature[11], 3); + + assign(test_msg_.signature[12], 4); + + assign(test_msg_.signature[13], 5); + + assign(test_msg_.signature[14], 6); + + assign(test_msg_.signature[15], 7); + + assign(test_msg_.signature[16], 0); + + assign(test_msg_.signature[17], 1); + + assign(test_msg_.signature[18], 2); + + assign(test_msg_.signature[19], 3); + + assign(test_msg_.signature[20], 4); + + assign(test_msg_.signature[21], 5); + + assign(test_msg_.signature[22], 6); + + assign(test_msg_.signature[23], 7); + + assign(test_msg_.signature[24], 0); + + assign(test_msg_.signature[25], 1); + + assign(test_msg_.signature[26], 2); + + assign(test_msg_.signature[27], 3); + + assign(test_msg_.signature[28], 4); + + assign(test_msg_.signature[29], 5); + + assign(test_msg_.signature[30], 6); + + assign(test_msg_.signature[31], 7); + + assign(test_msg_.signature[32], 0); + + assign(test_msg_.signature[33], 1); + + assign(test_msg_.signature[34], 2); + + assign(test_msg_.signature[35], 3); + + assign(test_msg_.signature[36], 4); + + assign(test_msg_.signature[37], 5); + + assign(test_msg_.signature[38], 6); + + assign(test_msg_.signature[39], 7); + + assign(test_msg_.signature[40], 0); + + assign(test_msg_.signature[41], 1); + + assign(test_msg_.signature[42], 2); + + assign(test_msg_.signature[43], 3); + + assign(test_msg_.signature[44], 4); + + assign(test_msg_.signature[45], 5); + + assign(test_msg_.signature[46], 6); + + assign(test_msg_.signature[47], 7); + + assign(test_msg_.signature[48], 0); + + assign(test_msg_.signature[49], 1); + + assign(test_msg_.signature[50], 2); + + assign(test_msg_.signature[51], 3); + + assign(test_msg_.signature[52], 4); + + assign(test_msg_.signature[53], 5); + + assign(test_msg_.signature[54], 6); + + assign(test_msg_.signature[55], 7); + + assign(test_msg_.signature[56], 0); + + assign(test_msg_.signature[57], 1); + + assign(test_msg_.signature[58], 2); + + assign(test_msg_.signature[59], 3); + + assign(test_msg_.signature[60], 4); + + assign(test_msg_.signature[61], 5); + + assign(test_msg_.signature[62], 6); + + assign(test_msg_.signature[63], 7); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_certificate_chain_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_certificate_chain_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgCertificateChainDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_certificate_chain_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgCertificateChainDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->certificate_chain_dep, + sizeof(msg->certificate_chain_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_certificate_chain_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.certificate_chain_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgCertificateChainDep); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x6470; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 135; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_certificate_chain_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_certificate_chain_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_certificate_chain_dep_t &lesser, + const sbp_msg_certificate_chain_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_certificate_chain_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_certificate_chain_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_certificate_chain_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_certificate_chain_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgCertificateChainDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgCertificateChainDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgCertificateChainDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgCertificateChainDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_signing_MsgCertificateChainDep0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_certificate_chain_dep_t test_msg_{}; + uint8_t encoded_frame_[135 + 8] = { 85, 5, 12, 66, 0, 135, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 20, 21, @@ -86,707 +552,1288 @@ TEST_F(Test_auto_check_sbp_signing_MsgCertificateChainDep0, Test) { 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 112, 100, }; + uint8_t encoded_payload_[135] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 0, 1, 2, 3, + 4, 5, 6, 7, 8, 9, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 232, 7, 3, 30, 12, 34, 59, 21, + 205, 91, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, + 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, + 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, + }; +}; + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_certificate_chain_dep_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgCertificateChainDep, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[135]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_certificate_chain_dep_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 135); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 135), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgCertificateChainDep, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 135); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 135), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[135]; + + EXPECT_EQ(sbp_msg_certificate_chain_dep_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 135), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[135]; + + for (uint8_t i = 0; i < 135; i++) { + EXPECT_EQ(sbp_msg_certificate_chain_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_certificate_chain_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 135); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgCertificateChainDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 135); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_dep_t msg{}; + + EXPECT_EQ(sbp_msg_certificate_chain_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_certificate_chain_dep_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_certificate_chain_dep_t test_msg{}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.corrections_certificate[0] = 20; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.corrections_certificate[1] = 21; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.corrections_certificate[2] = 22; + EXPECT_EQ(sbp_msg_certificate_chain_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.corrections_certificate[3] = 23; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.corrections_certificate[4] = 24; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.corrections_certificate[5] = 25; + EXPECT_EQ(sbp_message_send(&state, SbpMsgCertificateChainDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.corrections_certificate[6] = 26; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, Comparison) { + auto info = get_test_msg_info(); - test_msg.corrections_certificate[7] = 27; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[0], + greater.corrections_certificate[0]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[8] = 28; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[1], + greater.corrections_certificate[1]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[9] = 29; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[2], + greater.corrections_certificate[2]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[10] = 10; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[3], + greater.corrections_certificate[3]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[11] = 11; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[4], + greater.corrections_certificate[4]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[12] = 12; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[5], + greater.corrections_certificate[5]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[13] = 13; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[6], + greater.corrections_certificate[6]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[14] = 14; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[7], + greater.corrections_certificate[7]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[15] = 15; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[8], + greater.corrections_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[16] = 16; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[9], + greater.corrections_certificate[9]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[17] = 17; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[10], + greater.corrections_certificate[10]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[18] = 18; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[11], + greater.corrections_certificate[11]); + comparison_tests(lesser, greater); + } - test_msg.corrections_certificate[19] = 19; - test_msg.expiration.day = 30; - test_msg.expiration.hours = 12; - test_msg.expiration.minutes = 34; - test_msg.expiration.month = 3; - test_msg.expiration.ns = 123456789; - test_msg.expiration.seconds = 59; - test_msg.expiration.year = 2024; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[12], + greater.corrections_certificate[12]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[0] = 10; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[13], + greater.corrections_certificate[13]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[1] = 11; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[14], + greater.corrections_certificate[14]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[2] = 12; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[15], + greater.corrections_certificate[15]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[3] = 13; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[16], + greater.corrections_certificate[16]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[4] = 14; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[17], + greater.corrections_certificate[17]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[5] = 15; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[18], + greater.corrections_certificate[18]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[6] = 16; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corrections_certificate[19], + greater.corrections_certificate[19]); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.day, greater.expiration.day); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.hours, greater.expiration.hours); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.minutes, greater.expiration.minutes); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.month, greater.expiration.month); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.ns, greater.expiration.ns); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.seconds, greater.expiration.seconds); + comparison_tests(lesser, greater); + } + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.expiration.year, greater.expiration.year); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[7] = 17; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[0], + greater.intermediate_certificate[0]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[8] = 18; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[1], + greater.intermediate_certificate[1]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[9] = 19; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[2], + greater.intermediate_certificate[2]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[10] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[3], + greater.intermediate_certificate[3]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[11] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[4], + greater.intermediate_certificate[4]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[12] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[5], + greater.intermediate_certificate[5]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[13] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[6], + greater.intermediate_certificate[6]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[14] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[7], + greater.intermediate_certificate[7]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[15] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[8], + greater.intermediate_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[16] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[9], + greater.intermediate_certificate[9]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[17] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[10], + greater.intermediate_certificate[10]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[18] = 8; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[11], + greater.intermediate_certificate[11]); + comparison_tests(lesser, greater); + } - test_msg.intermediate_certificate[19] = 9; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[12], + greater.intermediate_certificate[12]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[0] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[13], + greater.intermediate_certificate[13]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[1] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[14], + greater.intermediate_certificate[14]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[2] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[15], + greater.intermediate_certificate[15]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[3] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[16], + greater.intermediate_certificate[16]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[4] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[17], + greater.intermediate_certificate[17]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[5] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[18], + greater.intermediate_certificate[18]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[6] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.intermediate_certificate[19], + greater.intermediate_certificate[19]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[7] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[0], + greater.root_certificate[0]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[8] = 8; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[1], + greater.root_certificate[1]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[9] = 9; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[2], + greater.root_certificate[2]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[10] = 10; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[3], + greater.root_certificate[3]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[11] = 11; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[4], + greater.root_certificate[4]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[12] = 12; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[5], + greater.root_certificate[5]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[13] = 13; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[6], + greater.root_certificate[6]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[14] = 14; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[7], + greater.root_certificate[7]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[15] = 15; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[8], + greater.root_certificate[8]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[16] = 16; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[9], + greater.root_certificate[9]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[17] = 17; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[10], + greater.root_certificate[10]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[18] = 18; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[11], + greater.root_certificate[11]); + comparison_tests(lesser, greater); + } - test_msg.root_certificate[19] = 19; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[12], + greater.root_certificate[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[0] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[13], + greater.root_certificate[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[1] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[14], + greater.root_certificate[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[2] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[15], + greater.root_certificate[15]); + comparison_tests(lesser, greater); + } - test_msg.signature[3] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[16], + greater.root_certificate[16]); + comparison_tests(lesser, greater); + } - test_msg.signature[4] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[17], + greater.root_certificate[17]); + comparison_tests(lesser, greater); + } - test_msg.signature[5] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[18], + greater.root_certificate[18]); + comparison_tests(lesser, greater); + } - test_msg.signature[6] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.root_certificate[19], + greater.root_certificate[19]); + comparison_tests(lesser, greater); + } - test_msg.signature[7] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[0], greater.signature[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[8] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[1], greater.signature[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[9] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[2], greater.signature[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[10] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[3], greater.signature[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[11] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[4], greater.signature[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[12] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[5], greater.signature[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[13] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[6], greater.signature[6]); + comparison_tests(lesser, greater); + } - test_msg.signature[14] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[7], greater.signature[7]); + comparison_tests(lesser, greater); + } - test_msg.signature[15] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[8], greater.signature[8]); + comparison_tests(lesser, greater); + } - test_msg.signature[16] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[9], greater.signature[9]); + comparison_tests(lesser, greater); + } - test_msg.signature[17] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[10], greater.signature[10]); + comparison_tests(lesser, greater); + } - test_msg.signature[18] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[11], greater.signature[11]); + comparison_tests(lesser, greater); + } - test_msg.signature[19] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[12], greater.signature[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[20] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[13], greater.signature[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[21] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[14], greater.signature[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[22] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[15], greater.signature[15]); + comparison_tests(lesser, greater); + } - test_msg.signature[23] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[16], greater.signature[16]); + comparison_tests(lesser, greater); + } - test_msg.signature[24] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[17], greater.signature[17]); + comparison_tests(lesser, greater); + } - test_msg.signature[25] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[18], greater.signature[18]); + comparison_tests(lesser, greater); + } - test_msg.signature[26] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[19], greater.signature[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[20], greater.signature[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[21], greater.signature[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[22], greater.signature[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[23], greater.signature[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[24], greater.signature[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[25], greater.signature[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[26], greater.signature[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[27], greater.signature[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[28], greater.signature[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[29], greater.signature[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[30], greater.signature[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[31], greater.signature[31]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[32], greater.signature[32]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[33], greater.signature[33]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[34], greater.signature[34]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[35], greater.signature[35]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[36], greater.signature[36]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[37], greater.signature[37]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[38], greater.signature[38]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[39], greater.signature[39]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[40], greater.signature[40]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[41], greater.signature[41]); + comparison_tests(lesser, greater); + } - test_msg.signature[27] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[42], greater.signature[42]); + comparison_tests(lesser, greater); + } - test_msg.signature[28] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[43], greater.signature[43]); + comparison_tests(lesser, greater); + } - test_msg.signature[29] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[44], greater.signature[44]); + comparison_tests(lesser, greater); + } - test_msg.signature[30] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[45], greater.signature[45]); + comparison_tests(lesser, greater); + } - test_msg.signature[31] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[46], greater.signature[46]); + comparison_tests(lesser, greater); + } - test_msg.signature[32] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[47], greater.signature[47]); + comparison_tests(lesser, greater); + } - test_msg.signature[33] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[48], greater.signature[48]); + comparison_tests(lesser, greater); + } - test_msg.signature[34] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[49], greater.signature[49]); + comparison_tests(lesser, greater); + } - test_msg.signature[35] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[50], greater.signature[50]); + comparison_tests(lesser, greater); + } - test_msg.signature[36] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[51], greater.signature[51]); + comparison_tests(lesser, greater); + } - test_msg.signature[37] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[52], greater.signature[52]); + comparison_tests(lesser, greater); + } - test_msg.signature[38] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[53], greater.signature[53]); + comparison_tests(lesser, greater); + } - test_msg.signature[39] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[54], greater.signature[54]); + comparison_tests(lesser, greater); + } - test_msg.signature[40] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[55], greater.signature[55]); + comparison_tests(lesser, greater); + } - test_msg.signature[41] = 1; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[56], greater.signature[56]); + comparison_tests(lesser, greater); + } - test_msg.signature[42] = 2; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[57], greater.signature[57]); + comparison_tests(lesser, greater); + } - test_msg.signature[43] = 3; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[58], greater.signature[58]); + comparison_tests(lesser, greater); + } - test_msg.signature[44] = 4; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[59], greater.signature[59]); + comparison_tests(lesser, greater); + } - test_msg.signature[45] = 5; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[60], greater.signature[60]); + comparison_tests(lesser, greater); + } - test_msg.signature[46] = 6; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[61], greater.signature[61]); + comparison_tests(lesser, greater); + } - test_msg.signature[47] = 7; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[62], greater.signature[62]); + comparison_tests(lesser, greater); + } - test_msg.signature[48] = 0; + { + sbp_msg_certificate_chain_dep_t lesser = info.test_msg; + sbp_msg_certificate_chain_dep_t greater = info.test_msg; + make_lesser_greater(lesser.signature[63], greater.signature[63]); + comparison_tests(lesser, greater); + } +} - test_msg.signature[49] = 1; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgCertificateChainDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_CERTIFICATE_CHAIN_DEP"); +} - test_msg.signature[50] = 2; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature[51] = 3; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.signature[52] = 4; + const sbp_msg_certificate_chain_dep_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_certificate_chain_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); - test_msg.signature[53] = 5; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.signature[54] = 6; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature[55] = 7; + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.certificate_chain_dep, info.test_msg); - test_msg.signature[56] = 0; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.certificate_chain_dep, info.test_msg); +} - test_msg.signature[57] = 1; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.signature[58] = 2; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature[59] = 3; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature[60] = 4; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.signature[61] = 5; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[135]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 135); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 135), 0); +} - test_msg.signature[62] = 6; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_certificate_chain_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 135); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signature[63] = 7; +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.corrections_certificate[0], 20) - << "incorrect value for last_msg_.corrections_certificate[0], expected " - "20, is " - << last_msg_.corrections_certificate[0]; - EXPECT_EQ(last_msg_.corrections_certificate[1], 21) - << "incorrect value for last_msg_.corrections_certificate[1], expected " - "21, is " - << last_msg_.corrections_certificate[1]; - EXPECT_EQ(last_msg_.corrections_certificate[2], 22) - << "incorrect value for last_msg_.corrections_certificate[2], expected " - "22, is " - << last_msg_.corrections_certificate[2]; - EXPECT_EQ(last_msg_.corrections_certificate[3], 23) - << "incorrect value for last_msg_.corrections_certificate[3], expected " - "23, is " - << last_msg_.corrections_certificate[3]; - EXPECT_EQ(last_msg_.corrections_certificate[4], 24) - << "incorrect value for last_msg_.corrections_certificate[4], expected " - "24, is " - << last_msg_.corrections_certificate[4]; - EXPECT_EQ(last_msg_.corrections_certificate[5], 25) - << "incorrect value for last_msg_.corrections_certificate[5], expected " - "25, is " - << last_msg_.corrections_certificate[5]; - EXPECT_EQ(last_msg_.corrections_certificate[6], 26) - << "incorrect value for last_msg_.corrections_certificate[6], expected " - "26, is " - << last_msg_.corrections_certificate[6]; - EXPECT_EQ(last_msg_.corrections_certificate[7], 27) - << "incorrect value for last_msg_.corrections_certificate[7], expected " - "27, is " - << last_msg_.corrections_certificate[7]; - EXPECT_EQ(last_msg_.corrections_certificate[8], 28) - << "incorrect value for last_msg_.corrections_certificate[8], expected " - "28, is " - << last_msg_.corrections_certificate[8]; - EXPECT_EQ(last_msg_.corrections_certificate[9], 29) - << "incorrect value for last_msg_.corrections_certificate[9], expected " - "29, is " - << last_msg_.corrections_certificate[9]; - EXPECT_EQ(last_msg_.corrections_certificate[10], 10) - << "incorrect value for last_msg_.corrections_certificate[10], expected " - "10, is " - << last_msg_.corrections_certificate[10]; - EXPECT_EQ(last_msg_.corrections_certificate[11], 11) - << "incorrect value for last_msg_.corrections_certificate[11], expected " - "11, is " - << last_msg_.corrections_certificate[11]; - EXPECT_EQ(last_msg_.corrections_certificate[12], 12) - << "incorrect value for last_msg_.corrections_certificate[12], expected " - "12, is " - << last_msg_.corrections_certificate[12]; - EXPECT_EQ(last_msg_.corrections_certificate[13], 13) - << "incorrect value for last_msg_.corrections_certificate[13], expected " - "13, is " - << last_msg_.corrections_certificate[13]; - EXPECT_EQ(last_msg_.corrections_certificate[14], 14) - << "incorrect value for last_msg_.corrections_certificate[14], expected " - "14, is " - << last_msg_.corrections_certificate[14]; - EXPECT_EQ(last_msg_.corrections_certificate[15], 15) - << "incorrect value for last_msg_.corrections_certificate[15], expected " - "15, is " - << last_msg_.corrections_certificate[15]; - EXPECT_EQ(last_msg_.corrections_certificate[16], 16) - << "incorrect value for last_msg_.corrections_certificate[16], expected " - "16, is " - << last_msg_.corrections_certificate[16]; - EXPECT_EQ(last_msg_.corrections_certificate[17], 17) - << "incorrect value for last_msg_.corrections_certificate[17], expected " - "17, is " - << last_msg_.corrections_certificate[17]; - EXPECT_EQ(last_msg_.corrections_certificate[18], 18) - << "incorrect value for last_msg_.corrections_certificate[18], expected " - "18, is " - << last_msg_.corrections_certificate[18]; - EXPECT_EQ(last_msg_.corrections_certificate[19], 19) - << "incorrect value for last_msg_.corrections_certificate[19], expected " - "19, is " - << last_msg_.corrections_certificate[19]; - EXPECT_EQ(last_msg_.expiration.day, 30) - << "incorrect value for last_msg_.expiration.day, expected 30, is " - << last_msg_.expiration.day; - EXPECT_EQ(last_msg_.expiration.hours, 12) - << "incorrect value for last_msg_.expiration.hours, expected 12, is " - << last_msg_.expiration.hours; - EXPECT_EQ(last_msg_.expiration.minutes, 34) - << "incorrect value for last_msg_.expiration.minutes, expected 34, is " - << last_msg_.expiration.minutes; - EXPECT_EQ(last_msg_.expiration.month, 3) - << "incorrect value for last_msg_.expiration.month, expected 3, is " - << last_msg_.expiration.month; - EXPECT_EQ(last_msg_.expiration.ns, 123456789) - << "incorrect value for last_msg_.expiration.ns, expected 123456789, is " - << last_msg_.expiration.ns; - EXPECT_EQ(last_msg_.expiration.seconds, 59) - << "incorrect value for last_msg_.expiration.seconds, expected 59, is " - << last_msg_.expiration.seconds; - EXPECT_EQ(last_msg_.expiration.year, 2024) - << "incorrect value for last_msg_.expiration.year, expected 2024, is " - << last_msg_.expiration.year; - EXPECT_EQ(last_msg_.intermediate_certificate[0], 10) - << "incorrect value for last_msg_.intermediate_certificate[0], expected " - "10, is " - << last_msg_.intermediate_certificate[0]; - EXPECT_EQ(last_msg_.intermediate_certificate[1], 11) - << "incorrect value for last_msg_.intermediate_certificate[1], expected " - "11, is " - << last_msg_.intermediate_certificate[1]; - EXPECT_EQ(last_msg_.intermediate_certificate[2], 12) - << "incorrect value for last_msg_.intermediate_certificate[2], expected " - "12, is " - << last_msg_.intermediate_certificate[2]; - EXPECT_EQ(last_msg_.intermediate_certificate[3], 13) - << "incorrect value for last_msg_.intermediate_certificate[3], expected " - "13, is " - << last_msg_.intermediate_certificate[3]; - EXPECT_EQ(last_msg_.intermediate_certificate[4], 14) - << "incorrect value for last_msg_.intermediate_certificate[4], expected " - "14, is " - << last_msg_.intermediate_certificate[4]; - EXPECT_EQ(last_msg_.intermediate_certificate[5], 15) - << "incorrect value for last_msg_.intermediate_certificate[5], expected " - "15, is " - << last_msg_.intermediate_certificate[5]; - EXPECT_EQ(last_msg_.intermediate_certificate[6], 16) - << "incorrect value for last_msg_.intermediate_certificate[6], expected " - "16, is " - << last_msg_.intermediate_certificate[6]; - EXPECT_EQ(last_msg_.intermediate_certificate[7], 17) - << "incorrect value for last_msg_.intermediate_certificate[7], expected " - "17, is " - << last_msg_.intermediate_certificate[7]; - EXPECT_EQ(last_msg_.intermediate_certificate[8], 18) - << "incorrect value for last_msg_.intermediate_certificate[8], expected " - "18, is " - << last_msg_.intermediate_certificate[8]; - EXPECT_EQ(last_msg_.intermediate_certificate[9], 19) - << "incorrect value for last_msg_.intermediate_certificate[9], expected " - "19, is " - << last_msg_.intermediate_certificate[9]; - EXPECT_EQ(last_msg_.intermediate_certificate[10], 0) - << "incorrect value for last_msg_.intermediate_certificate[10], expected " - "0, is " - << last_msg_.intermediate_certificate[10]; - EXPECT_EQ(last_msg_.intermediate_certificate[11], 1) - << "incorrect value for last_msg_.intermediate_certificate[11], expected " - "1, is " - << last_msg_.intermediate_certificate[11]; - EXPECT_EQ(last_msg_.intermediate_certificate[12], 2) - << "incorrect value for last_msg_.intermediate_certificate[12], expected " - "2, is " - << last_msg_.intermediate_certificate[12]; - EXPECT_EQ(last_msg_.intermediate_certificate[13], 3) - << "incorrect value for last_msg_.intermediate_certificate[13], expected " - "3, is " - << last_msg_.intermediate_certificate[13]; - EXPECT_EQ(last_msg_.intermediate_certificate[14], 4) - << "incorrect value for last_msg_.intermediate_certificate[14], expected " - "4, is " - << last_msg_.intermediate_certificate[14]; - EXPECT_EQ(last_msg_.intermediate_certificate[15], 5) - << "incorrect value for last_msg_.intermediate_certificate[15], expected " - "5, is " - << last_msg_.intermediate_certificate[15]; - EXPECT_EQ(last_msg_.intermediate_certificate[16], 6) - << "incorrect value for last_msg_.intermediate_certificate[16], expected " - "6, is " - << last_msg_.intermediate_certificate[16]; - EXPECT_EQ(last_msg_.intermediate_certificate[17], 7) - << "incorrect value for last_msg_.intermediate_certificate[17], expected " - "7, is " - << last_msg_.intermediate_certificate[17]; - EXPECT_EQ(last_msg_.intermediate_certificate[18], 8) - << "incorrect value for last_msg_.intermediate_certificate[18], expected " - "8, is " - << last_msg_.intermediate_certificate[18]; - EXPECT_EQ(last_msg_.intermediate_certificate[19], 9) - << "incorrect value for last_msg_.intermediate_certificate[19], expected " - "9, is " - << last_msg_.intermediate_certificate[19]; - EXPECT_EQ(last_msg_.root_certificate[0], 0) - << "incorrect value for last_msg_.root_certificate[0], expected 0, is " - << last_msg_.root_certificate[0]; - EXPECT_EQ(last_msg_.root_certificate[1], 1) - << "incorrect value for last_msg_.root_certificate[1], expected 1, is " - << last_msg_.root_certificate[1]; - EXPECT_EQ(last_msg_.root_certificate[2], 2) - << "incorrect value for last_msg_.root_certificate[2], expected 2, is " - << last_msg_.root_certificate[2]; - EXPECT_EQ(last_msg_.root_certificate[3], 3) - << "incorrect value for last_msg_.root_certificate[3], expected 3, is " - << last_msg_.root_certificate[3]; - EXPECT_EQ(last_msg_.root_certificate[4], 4) - << "incorrect value for last_msg_.root_certificate[4], expected 4, is " - << last_msg_.root_certificate[4]; - EXPECT_EQ(last_msg_.root_certificate[5], 5) - << "incorrect value for last_msg_.root_certificate[5], expected 5, is " - << last_msg_.root_certificate[5]; - EXPECT_EQ(last_msg_.root_certificate[6], 6) - << "incorrect value for last_msg_.root_certificate[6], expected 6, is " - << last_msg_.root_certificate[6]; - EXPECT_EQ(last_msg_.root_certificate[7], 7) - << "incorrect value for last_msg_.root_certificate[7], expected 7, is " - << last_msg_.root_certificate[7]; - EXPECT_EQ(last_msg_.root_certificate[8], 8) - << "incorrect value for last_msg_.root_certificate[8], expected 8, is " - << last_msg_.root_certificate[8]; - EXPECT_EQ(last_msg_.root_certificate[9], 9) - << "incorrect value for last_msg_.root_certificate[9], expected 9, is " - << last_msg_.root_certificate[9]; - EXPECT_EQ(last_msg_.root_certificate[10], 10) - << "incorrect value for last_msg_.root_certificate[10], expected 10, is " - << last_msg_.root_certificate[10]; - EXPECT_EQ(last_msg_.root_certificate[11], 11) - << "incorrect value for last_msg_.root_certificate[11], expected 11, is " - << last_msg_.root_certificate[11]; - EXPECT_EQ(last_msg_.root_certificate[12], 12) - << "incorrect value for last_msg_.root_certificate[12], expected 12, is " - << last_msg_.root_certificate[12]; - EXPECT_EQ(last_msg_.root_certificate[13], 13) - << "incorrect value for last_msg_.root_certificate[13], expected 13, is " - << last_msg_.root_certificate[13]; - EXPECT_EQ(last_msg_.root_certificate[14], 14) - << "incorrect value for last_msg_.root_certificate[14], expected 14, is " - << last_msg_.root_certificate[14]; - EXPECT_EQ(last_msg_.root_certificate[15], 15) - << "incorrect value for last_msg_.root_certificate[15], expected 15, is " - << last_msg_.root_certificate[15]; - EXPECT_EQ(last_msg_.root_certificate[16], 16) - << "incorrect value for last_msg_.root_certificate[16], expected 16, is " - << last_msg_.root_certificate[16]; - EXPECT_EQ(last_msg_.root_certificate[17], 17) - << "incorrect value for last_msg_.root_certificate[17], expected 17, is " - << last_msg_.root_certificate[17]; - EXPECT_EQ(last_msg_.root_certificate[18], 18) - << "incorrect value for last_msg_.root_certificate[18], expected 18, is " - << last_msg_.root_certificate[18]; - EXPECT_EQ(last_msg_.root_certificate[19], 19) - << "incorrect value for last_msg_.root_certificate[19], expected 19, is " - << last_msg_.root_certificate[19]; - EXPECT_EQ(last_msg_.signature[0], 0) - << "incorrect value for last_msg_.signature[0], expected 0, is " - << last_msg_.signature[0]; - EXPECT_EQ(last_msg_.signature[1], 1) - << "incorrect value for last_msg_.signature[1], expected 1, is " - << last_msg_.signature[1]; - EXPECT_EQ(last_msg_.signature[2], 2) - << "incorrect value for last_msg_.signature[2], expected 2, is " - << last_msg_.signature[2]; - EXPECT_EQ(last_msg_.signature[3], 3) - << "incorrect value for last_msg_.signature[3], expected 3, is " - << last_msg_.signature[3]; - EXPECT_EQ(last_msg_.signature[4], 4) - << "incorrect value for last_msg_.signature[4], expected 4, is " - << last_msg_.signature[4]; - EXPECT_EQ(last_msg_.signature[5], 5) - << "incorrect value for last_msg_.signature[5], expected 5, is " - << last_msg_.signature[5]; - EXPECT_EQ(last_msg_.signature[6], 6) - << "incorrect value for last_msg_.signature[6], expected 6, is " - << last_msg_.signature[6]; - EXPECT_EQ(last_msg_.signature[7], 7) - << "incorrect value for last_msg_.signature[7], expected 7, is " - << last_msg_.signature[7]; - EXPECT_EQ(last_msg_.signature[8], 0) - << "incorrect value for last_msg_.signature[8], expected 0, is " - << last_msg_.signature[8]; - EXPECT_EQ(last_msg_.signature[9], 1) - << "incorrect value for last_msg_.signature[9], expected 1, is " - << last_msg_.signature[9]; - EXPECT_EQ(last_msg_.signature[10], 2) - << "incorrect value for last_msg_.signature[10], expected 2, is " - << last_msg_.signature[10]; - EXPECT_EQ(last_msg_.signature[11], 3) - << "incorrect value for last_msg_.signature[11], expected 3, is " - << last_msg_.signature[11]; - EXPECT_EQ(last_msg_.signature[12], 4) - << "incorrect value for last_msg_.signature[12], expected 4, is " - << last_msg_.signature[12]; - EXPECT_EQ(last_msg_.signature[13], 5) - << "incorrect value for last_msg_.signature[13], expected 5, is " - << last_msg_.signature[13]; - EXPECT_EQ(last_msg_.signature[14], 6) - << "incorrect value for last_msg_.signature[14], expected 6, is " - << last_msg_.signature[14]; - EXPECT_EQ(last_msg_.signature[15], 7) - << "incorrect value for last_msg_.signature[15], expected 7, is " - << last_msg_.signature[15]; - EXPECT_EQ(last_msg_.signature[16], 0) - << "incorrect value for last_msg_.signature[16], expected 0, is " - << last_msg_.signature[16]; - EXPECT_EQ(last_msg_.signature[17], 1) - << "incorrect value for last_msg_.signature[17], expected 1, is " - << last_msg_.signature[17]; - EXPECT_EQ(last_msg_.signature[18], 2) - << "incorrect value for last_msg_.signature[18], expected 2, is " - << last_msg_.signature[18]; - EXPECT_EQ(last_msg_.signature[19], 3) - << "incorrect value for last_msg_.signature[19], expected 3, is " - << last_msg_.signature[19]; - EXPECT_EQ(last_msg_.signature[20], 4) - << "incorrect value for last_msg_.signature[20], expected 4, is " - << last_msg_.signature[20]; - EXPECT_EQ(last_msg_.signature[21], 5) - << "incorrect value for last_msg_.signature[21], expected 5, is " - << last_msg_.signature[21]; - EXPECT_EQ(last_msg_.signature[22], 6) - << "incorrect value for last_msg_.signature[22], expected 6, is " - << last_msg_.signature[22]; - EXPECT_EQ(last_msg_.signature[23], 7) - << "incorrect value for last_msg_.signature[23], expected 7, is " - << last_msg_.signature[23]; - EXPECT_EQ(last_msg_.signature[24], 0) - << "incorrect value for last_msg_.signature[24], expected 0, is " - << last_msg_.signature[24]; - EXPECT_EQ(last_msg_.signature[25], 1) - << "incorrect value for last_msg_.signature[25], expected 1, is " - << last_msg_.signature[25]; - EXPECT_EQ(last_msg_.signature[26], 2) - << "incorrect value for last_msg_.signature[26], expected 2, is " - << last_msg_.signature[26]; - EXPECT_EQ(last_msg_.signature[27], 3) - << "incorrect value for last_msg_.signature[27], expected 3, is " - << last_msg_.signature[27]; - EXPECT_EQ(last_msg_.signature[28], 4) - << "incorrect value for last_msg_.signature[28], expected 4, is " - << last_msg_.signature[28]; - EXPECT_EQ(last_msg_.signature[29], 5) - << "incorrect value for last_msg_.signature[29], expected 5, is " - << last_msg_.signature[29]; - EXPECT_EQ(last_msg_.signature[30], 6) - << "incorrect value for last_msg_.signature[30], expected 6, is " - << last_msg_.signature[30]; - EXPECT_EQ(last_msg_.signature[31], 7) - << "incorrect value for last_msg_.signature[31], expected 7, is " - << last_msg_.signature[31]; - EXPECT_EQ(last_msg_.signature[32], 0) - << "incorrect value for last_msg_.signature[32], expected 0, is " - << last_msg_.signature[32]; - EXPECT_EQ(last_msg_.signature[33], 1) - << "incorrect value for last_msg_.signature[33], expected 1, is " - << last_msg_.signature[33]; - EXPECT_EQ(last_msg_.signature[34], 2) - << "incorrect value for last_msg_.signature[34], expected 2, is " - << last_msg_.signature[34]; - EXPECT_EQ(last_msg_.signature[35], 3) - << "incorrect value for last_msg_.signature[35], expected 3, is " - << last_msg_.signature[35]; - EXPECT_EQ(last_msg_.signature[36], 4) - << "incorrect value for last_msg_.signature[36], expected 4, is " - << last_msg_.signature[36]; - EXPECT_EQ(last_msg_.signature[37], 5) - << "incorrect value for last_msg_.signature[37], expected 5, is " - << last_msg_.signature[37]; - EXPECT_EQ(last_msg_.signature[38], 6) - << "incorrect value for last_msg_.signature[38], expected 6, is " - << last_msg_.signature[38]; - EXPECT_EQ(last_msg_.signature[39], 7) - << "incorrect value for last_msg_.signature[39], expected 7, is " - << last_msg_.signature[39]; - EXPECT_EQ(last_msg_.signature[40], 0) - << "incorrect value for last_msg_.signature[40], expected 0, is " - << last_msg_.signature[40]; - EXPECT_EQ(last_msg_.signature[41], 1) - << "incorrect value for last_msg_.signature[41], expected 1, is " - << last_msg_.signature[41]; - EXPECT_EQ(last_msg_.signature[42], 2) - << "incorrect value for last_msg_.signature[42], expected 2, is " - << last_msg_.signature[42]; - EXPECT_EQ(last_msg_.signature[43], 3) - << "incorrect value for last_msg_.signature[43], expected 3, is " - << last_msg_.signature[43]; - EXPECT_EQ(last_msg_.signature[44], 4) - << "incorrect value for last_msg_.signature[44], expected 4, is " - << last_msg_.signature[44]; - EXPECT_EQ(last_msg_.signature[45], 5) - << "incorrect value for last_msg_.signature[45], expected 5, is " - << last_msg_.signature[45]; - EXPECT_EQ(last_msg_.signature[46], 6) - << "incorrect value for last_msg_.signature[46], expected 6, is " - << last_msg_.signature[46]; - EXPECT_EQ(last_msg_.signature[47], 7) - << "incorrect value for last_msg_.signature[47], expected 7, is " - << last_msg_.signature[47]; - EXPECT_EQ(last_msg_.signature[48], 0) - << "incorrect value for last_msg_.signature[48], expected 0, is " - << last_msg_.signature[48]; - EXPECT_EQ(last_msg_.signature[49], 1) - << "incorrect value for last_msg_.signature[49], expected 1, is " - << last_msg_.signature[49]; - EXPECT_EQ(last_msg_.signature[50], 2) - << "incorrect value for last_msg_.signature[50], expected 2, is " - << last_msg_.signature[50]; - EXPECT_EQ(last_msg_.signature[51], 3) - << "incorrect value for last_msg_.signature[51], expected 3, is " - << last_msg_.signature[51]; - EXPECT_EQ(last_msg_.signature[52], 4) - << "incorrect value for last_msg_.signature[52], expected 4, is " - << last_msg_.signature[52]; - EXPECT_EQ(last_msg_.signature[53], 5) - << "incorrect value for last_msg_.signature[53], expected 5, is " - << last_msg_.signature[53]; - EXPECT_EQ(last_msg_.signature[54], 6) - << "incorrect value for last_msg_.signature[54], expected 6, is " - << last_msg_.signature[54]; - EXPECT_EQ(last_msg_.signature[55], 7) - << "incorrect value for last_msg_.signature[55], expected 7, is " - << last_msg_.signature[55]; - EXPECT_EQ(last_msg_.signature[56], 0) - << "incorrect value for last_msg_.signature[56], expected 0, is " - << last_msg_.signature[56]; - EXPECT_EQ(last_msg_.signature[57], 1) - << "incorrect value for last_msg_.signature[57], expected 1, is " - << last_msg_.signature[57]; - EXPECT_EQ(last_msg_.signature[58], 2) - << "incorrect value for last_msg_.signature[58], expected 2, is " - << last_msg_.signature[58]; - EXPECT_EQ(last_msg_.signature[59], 3) - << "incorrect value for last_msg_.signature[59], expected 3, is " - << last_msg_.signature[59]; - EXPECT_EQ(last_msg_.signature[60], 4) - << "incorrect value for last_msg_.signature[60], expected 4, is " - << last_msg_.signature[60]; - EXPECT_EQ(last_msg_.signature[61], 5) - << "incorrect value for last_msg_.signature[61], expected 5, is " - << last_msg_.signature[61]; - EXPECT_EQ(last_msg_.signature[62], 6) - << "incorrect value for last_msg_.signature[62], expected 6, is " - << last_msg_.signature[62]; - EXPECT_EQ(last_msg_.signature[63], 7) - << "incorrect value for last_msg_.signature[63], expected 7, is " - << last_msg_.signature[63]; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgCertificateChainDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_signing_MsgCertificateChainDep0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgCertificateChainDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaCertificate.cc b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaCertificate.cc index 3e0102b8ee..c38db7c025 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaCertificate.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaCertificate.cc @@ -16,1561 +16,3147 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEcdsaCertificate0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEcdsaCertificate0 : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEcdsaCertificate0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + Testauto_check_sbp_signing_MsgEcdsaCertificate0() { + assign(test_msg_.certificate_bytes[0], 180); - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ecdsa_certificate_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ecdsa_certificate_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + assign(test_msg_.certificate_bytes[1], 160); -TEST_F(Test_auto_check_sbp_signing_MsgEcdsaCertificate0, Test) { - uint8_t encoded_frame[] = { - 85, 4, 12, 66, 0, 253, 48, 10, 11, 12, 13, 2, 180, 160, 116, - 77, 243, 28, 173, 36, 86, 33, 8, 31, 120, 73, 64, 169, 148, 224, - 57, 95, 17, 40, 213, 92, 195, 146, 235, 228, 177, 101, 82, 182, 25, - 172, 170, 250, 236, 7, 119, 4, 201, 10, 14, 208, 47, 126, 49, 210, - 174, 75, 221, 203, 24, 66, 52, 35, 26, 30, 140, 111, 246, 39, 226, - 205, 198, 178, 196, 5, 81, 9, 44, 164, 163, 214, 138, 123, 76, 74, - 237, 121, 13, 137, 186, 97, 193, 189, 200, 124, 69, 115, 230, 159, 185, - 158, 51, 12, 225, 65, 192, 105, 56, 41, 85, 133, 19, 217, 166, 48, - 139, 131, 96, 216, 98, 147, 132, 234, 167, 248, 247, 32, 239, 194, 188, - 254, 114, 117, 83, 25, 251, 191, 104, 240, 118, 68, 42, 93, 18, 16, - 37, 232, 99, 179, 23, 90, 94, 136, 6, 125, 91, 255, 15, 71, 43, - 46, 25, 252, 229, 80, 143, 58, 241, 11, 62, 181, 155, 53, 153, 149, - 152, 227, 150, 87, 112, 165, 2, 128, 231, 25, 157, 244, 204, 108, 253, - 127, 122, 145, 113, 162, 197, 171, 199, 54, 184, 222, 206, 67, 144, 78, - 187, 207, 60, 211, 141, 135, 106, 220, 79, 183, 245, 21, 161, 168, 34, - 129, 50, 176, 1, 218, 20, 130, 59, 249, 109, 219, 0, 100, 103, 55, - 29, 242, 110, 154, 190, 233, 142, 45, 61, 215, 202, 238, 88, 209, 70, - 63, 151, 27, 102, 219, 30, - }; + assign(test_msg_.certificate_bytes[2], 116); + + assign(test_msg_.certificate_bytes[3], 77); + + assign(test_msg_.certificate_bytes[4], 243); + + assign(test_msg_.certificate_bytes[5], 28); + + assign(test_msg_.certificate_bytes[6], 173); + + assign(test_msg_.certificate_bytes[7], 36); + + assign(test_msg_.certificate_bytes[8], 86); + + assign(test_msg_.certificate_bytes[9], 33); - sbp_msg_ecdsa_certificate_t test_msg{}; + assign(test_msg_.certificate_bytes[10], 8); - test_msg.certificate_bytes[0] = 180; + assign(test_msg_.certificate_bytes[11], 31); - test_msg.certificate_bytes[1] = 160; + assign(test_msg_.certificate_bytes[12], 120); - test_msg.certificate_bytes[2] = 116; + assign(test_msg_.certificate_bytes[13], 73); - test_msg.certificate_bytes[3] = 77; + assign(test_msg_.certificate_bytes[14], 64); - test_msg.certificate_bytes[4] = 243; + assign(test_msg_.certificate_bytes[15], 169); - test_msg.certificate_bytes[5] = 28; + assign(test_msg_.certificate_bytes[16], 148); - test_msg.certificate_bytes[6] = 173; + assign(test_msg_.certificate_bytes[17], 224); - test_msg.certificate_bytes[7] = 36; + assign(test_msg_.certificate_bytes[18], 57); - test_msg.certificate_bytes[8] = 86; + assign(test_msg_.certificate_bytes[19], 95); - test_msg.certificate_bytes[9] = 33; + assign(test_msg_.certificate_bytes[20], 17); - test_msg.certificate_bytes[10] = 8; + assign(test_msg_.certificate_bytes[21], 40); - test_msg.certificate_bytes[11] = 31; + assign(test_msg_.certificate_bytes[22], 213); - test_msg.certificate_bytes[12] = 120; + assign(test_msg_.certificate_bytes[23], 92); - test_msg.certificate_bytes[13] = 73; + assign(test_msg_.certificate_bytes[24], 195); - test_msg.certificate_bytes[14] = 64; + assign(test_msg_.certificate_bytes[25], 146); - test_msg.certificate_bytes[15] = 169; + assign(test_msg_.certificate_bytes[26], 235); - test_msg.certificate_bytes[16] = 148; + assign(test_msg_.certificate_bytes[27], 228); - test_msg.certificate_bytes[17] = 224; + assign(test_msg_.certificate_bytes[28], 177); - test_msg.certificate_bytes[18] = 57; + assign(test_msg_.certificate_bytes[29], 101); - test_msg.certificate_bytes[19] = 95; + assign(test_msg_.certificate_bytes[30], 82); - test_msg.certificate_bytes[20] = 17; + assign(test_msg_.certificate_bytes[31], 182); - test_msg.certificate_bytes[21] = 40; + assign(test_msg_.certificate_bytes[32], 25); - test_msg.certificate_bytes[22] = 213; + assign(test_msg_.certificate_bytes[33], 172); - test_msg.certificate_bytes[23] = 92; + assign(test_msg_.certificate_bytes[34], 170); - test_msg.certificate_bytes[24] = 195; + assign(test_msg_.certificate_bytes[35], 250); - test_msg.certificate_bytes[25] = 146; + assign(test_msg_.certificate_bytes[36], 236); - test_msg.certificate_bytes[26] = 235; + assign(test_msg_.certificate_bytes[37], 7); - test_msg.certificate_bytes[27] = 228; + assign(test_msg_.certificate_bytes[38], 119); - test_msg.certificate_bytes[28] = 177; + assign(test_msg_.certificate_bytes[39], 4); - test_msg.certificate_bytes[29] = 101; + assign(test_msg_.certificate_bytes[40], 201); - test_msg.certificate_bytes[30] = 82; + assign(test_msg_.certificate_bytes[41], 10); - test_msg.certificate_bytes[31] = 182; + assign(test_msg_.certificate_bytes[42], 14); - test_msg.certificate_bytes[32] = 25; + assign(test_msg_.certificate_bytes[43], 208); - test_msg.certificate_bytes[33] = 172; + assign(test_msg_.certificate_bytes[44], 47); - test_msg.certificate_bytes[34] = 170; + assign(test_msg_.certificate_bytes[45], 126); - test_msg.certificate_bytes[35] = 250; + assign(test_msg_.certificate_bytes[46], 49); - test_msg.certificate_bytes[36] = 236; + assign(test_msg_.certificate_bytes[47], 210); - test_msg.certificate_bytes[37] = 7; + assign(test_msg_.certificate_bytes[48], 174); - test_msg.certificate_bytes[38] = 119; + assign(test_msg_.certificate_bytes[49], 75); - test_msg.certificate_bytes[39] = 4; + assign(test_msg_.certificate_bytes[50], 221); - test_msg.certificate_bytes[40] = 201; + assign(test_msg_.certificate_bytes[51], 203); - test_msg.certificate_bytes[41] = 10; + assign(test_msg_.certificate_bytes[52], 24); - test_msg.certificate_bytes[42] = 14; + assign(test_msg_.certificate_bytes[53], 66); - test_msg.certificate_bytes[43] = 208; + assign(test_msg_.certificate_bytes[54], 52); - test_msg.certificate_bytes[44] = 47; + assign(test_msg_.certificate_bytes[55], 35); - test_msg.certificate_bytes[45] = 126; + assign(test_msg_.certificate_bytes[56], 26); - test_msg.certificate_bytes[46] = 49; + assign(test_msg_.certificate_bytes[57], 30); - test_msg.certificate_bytes[47] = 210; + assign(test_msg_.certificate_bytes[58], 140); - test_msg.certificate_bytes[48] = 174; + assign(test_msg_.certificate_bytes[59], 111); - test_msg.certificate_bytes[49] = 75; + assign(test_msg_.certificate_bytes[60], 246); - test_msg.certificate_bytes[50] = 221; + assign(test_msg_.certificate_bytes[61], 39); - test_msg.certificate_bytes[51] = 203; + assign(test_msg_.certificate_bytes[62], 226); - test_msg.certificate_bytes[52] = 24; + assign(test_msg_.certificate_bytes[63], 205); - test_msg.certificate_bytes[53] = 66; + assign(test_msg_.certificate_bytes[64], 198); - test_msg.certificate_bytes[54] = 52; + assign(test_msg_.certificate_bytes[65], 178); - test_msg.certificate_bytes[55] = 35; + assign(test_msg_.certificate_bytes[66], 196); - test_msg.certificate_bytes[56] = 26; + assign(test_msg_.certificate_bytes[67], 5); - test_msg.certificate_bytes[57] = 30; + assign(test_msg_.certificate_bytes[68], 81); - test_msg.certificate_bytes[58] = 140; + assign(test_msg_.certificate_bytes[69], 9); - test_msg.certificate_bytes[59] = 111; + assign(test_msg_.certificate_bytes[70], 44); - test_msg.certificate_bytes[60] = 246; + assign(test_msg_.certificate_bytes[71], 164); - test_msg.certificate_bytes[61] = 39; + assign(test_msg_.certificate_bytes[72], 163); - test_msg.certificate_bytes[62] = 226; + assign(test_msg_.certificate_bytes[73], 214); - test_msg.certificate_bytes[63] = 205; + assign(test_msg_.certificate_bytes[74], 138); - test_msg.certificate_bytes[64] = 198; + assign(test_msg_.certificate_bytes[75], 123); - test_msg.certificate_bytes[65] = 178; + assign(test_msg_.certificate_bytes[76], 76); - test_msg.certificate_bytes[66] = 196; + assign(test_msg_.certificate_bytes[77], 74); - test_msg.certificate_bytes[67] = 5; + assign(test_msg_.certificate_bytes[78], 237); - test_msg.certificate_bytes[68] = 81; + assign(test_msg_.certificate_bytes[79], 121); - test_msg.certificate_bytes[69] = 9; + assign(test_msg_.certificate_bytes[80], 13); - test_msg.certificate_bytes[70] = 44; + assign(test_msg_.certificate_bytes[81], 137); - test_msg.certificate_bytes[71] = 164; + assign(test_msg_.certificate_bytes[82], 186); - test_msg.certificate_bytes[72] = 163; + assign(test_msg_.certificate_bytes[83], 97); - test_msg.certificate_bytes[73] = 214; + assign(test_msg_.certificate_bytes[84], 193); - test_msg.certificate_bytes[74] = 138; + assign(test_msg_.certificate_bytes[85], 189); - test_msg.certificate_bytes[75] = 123; + assign(test_msg_.certificate_bytes[86], 200); - test_msg.certificate_bytes[76] = 76; + assign(test_msg_.certificate_bytes[87], 124); - test_msg.certificate_bytes[77] = 74; + assign(test_msg_.certificate_bytes[88], 69); - test_msg.certificate_bytes[78] = 237; + assign(test_msg_.certificate_bytes[89], 115); - test_msg.certificate_bytes[79] = 121; + assign(test_msg_.certificate_bytes[90], 230); - test_msg.certificate_bytes[80] = 13; + assign(test_msg_.certificate_bytes[91], 159); - test_msg.certificate_bytes[81] = 137; + assign(test_msg_.certificate_bytes[92], 185); - test_msg.certificate_bytes[82] = 186; + assign(test_msg_.certificate_bytes[93], 158); - test_msg.certificate_bytes[83] = 97; + assign(test_msg_.certificate_bytes[94], 51); - test_msg.certificate_bytes[84] = 193; + assign(test_msg_.certificate_bytes[95], 12); - test_msg.certificate_bytes[85] = 189; + assign(test_msg_.certificate_bytes[96], 225); - test_msg.certificate_bytes[86] = 200; + assign(test_msg_.certificate_bytes[97], 65); - test_msg.certificate_bytes[87] = 124; + assign(test_msg_.certificate_bytes[98], 192); - test_msg.certificate_bytes[88] = 69; + assign(test_msg_.certificate_bytes[99], 105); - test_msg.certificate_bytes[89] = 115; + assign(test_msg_.certificate_bytes[100], 56); - test_msg.certificate_bytes[90] = 230; + assign(test_msg_.certificate_bytes[101], 41); - test_msg.certificate_bytes[91] = 159; + assign(test_msg_.certificate_bytes[102], 85); - test_msg.certificate_bytes[92] = 185; + assign(test_msg_.certificate_bytes[103], 133); - test_msg.certificate_bytes[93] = 158; + assign(test_msg_.certificate_bytes[104], 19); - test_msg.certificate_bytes[94] = 51; + assign(test_msg_.certificate_bytes[105], 217); - test_msg.certificate_bytes[95] = 12; + assign(test_msg_.certificate_bytes[106], 166); - test_msg.certificate_bytes[96] = 225; + assign(test_msg_.certificate_bytes[107], 48); - test_msg.certificate_bytes[97] = 65; + assign(test_msg_.certificate_bytes[108], 139); - test_msg.certificate_bytes[98] = 192; + assign(test_msg_.certificate_bytes[109], 131); - test_msg.certificate_bytes[99] = 105; + assign(test_msg_.certificate_bytes[110], 96); - test_msg.certificate_bytes[100] = 56; + assign(test_msg_.certificate_bytes[111], 216); - test_msg.certificate_bytes[101] = 41; + assign(test_msg_.certificate_bytes[112], 98); - test_msg.certificate_bytes[102] = 85; + assign(test_msg_.certificate_bytes[113], 147); - test_msg.certificate_bytes[103] = 133; + assign(test_msg_.certificate_bytes[114], 132); - test_msg.certificate_bytes[104] = 19; + assign(test_msg_.certificate_bytes[115], 234); - test_msg.certificate_bytes[105] = 217; + assign(test_msg_.certificate_bytes[116], 167); - test_msg.certificate_bytes[106] = 166; + assign(test_msg_.certificate_bytes[117], 248); - test_msg.certificate_bytes[107] = 48; + assign(test_msg_.certificate_bytes[118], 247); - test_msg.certificate_bytes[108] = 139; + assign(test_msg_.certificate_bytes[119], 32); - test_msg.certificate_bytes[109] = 131; + assign(test_msg_.certificate_bytes[120], 239); - test_msg.certificate_bytes[110] = 96; + assign(test_msg_.certificate_bytes[121], 194); - test_msg.certificate_bytes[111] = 216; + assign(test_msg_.certificate_bytes[122], 188); - test_msg.certificate_bytes[112] = 98; + assign(test_msg_.certificate_bytes[123], 254); - test_msg.certificate_bytes[113] = 147; + assign(test_msg_.certificate_bytes[124], 114); - test_msg.certificate_bytes[114] = 132; + assign(test_msg_.certificate_bytes[125], 117); - test_msg.certificate_bytes[115] = 234; + assign(test_msg_.certificate_bytes[126], 83); - test_msg.certificate_bytes[116] = 167; + assign(test_msg_.certificate_bytes[127], 25); - test_msg.certificate_bytes[117] = 248; + assign(test_msg_.certificate_bytes[128], 251); - test_msg.certificate_bytes[118] = 247; + assign(test_msg_.certificate_bytes[129], 191); - test_msg.certificate_bytes[119] = 32; + assign(test_msg_.certificate_bytes[130], 104); - test_msg.certificate_bytes[120] = 239; + assign(test_msg_.certificate_bytes[131], 240); - test_msg.certificate_bytes[121] = 194; + assign(test_msg_.certificate_bytes[132], 118); - test_msg.certificate_bytes[122] = 188; + assign(test_msg_.certificate_bytes[133], 68); - test_msg.certificate_bytes[123] = 254; + assign(test_msg_.certificate_bytes[134], 42); - test_msg.certificate_bytes[124] = 114; + assign(test_msg_.certificate_bytes[135], 93); - test_msg.certificate_bytes[125] = 117; + assign(test_msg_.certificate_bytes[136], 18); - test_msg.certificate_bytes[126] = 83; + assign(test_msg_.certificate_bytes[137], 16); - test_msg.certificate_bytes[127] = 25; + assign(test_msg_.certificate_bytes[138], 37); - test_msg.certificate_bytes[128] = 251; + assign(test_msg_.certificate_bytes[139], 232); - test_msg.certificate_bytes[129] = 191; + assign(test_msg_.certificate_bytes[140], 99); - test_msg.certificate_bytes[130] = 104; + assign(test_msg_.certificate_bytes[141], 179); - test_msg.certificate_bytes[131] = 240; + assign(test_msg_.certificate_bytes[142], 23); - test_msg.certificate_bytes[132] = 118; + assign(test_msg_.certificate_bytes[143], 90); - test_msg.certificate_bytes[133] = 68; + assign(test_msg_.certificate_bytes[144], 94); - test_msg.certificate_bytes[134] = 42; + assign(test_msg_.certificate_bytes[145], 136); - test_msg.certificate_bytes[135] = 93; + assign(test_msg_.certificate_bytes[146], 6); - test_msg.certificate_bytes[136] = 18; + assign(test_msg_.certificate_bytes[147], 125); - test_msg.certificate_bytes[137] = 16; + assign(test_msg_.certificate_bytes[148], 91); - test_msg.certificate_bytes[138] = 37; + assign(test_msg_.certificate_bytes[149], 255); - test_msg.certificate_bytes[139] = 232; + assign(test_msg_.certificate_bytes[150], 15); - test_msg.certificate_bytes[140] = 99; + assign(test_msg_.certificate_bytes[151], 71); - test_msg.certificate_bytes[141] = 179; + assign(test_msg_.certificate_bytes[152], 43); - test_msg.certificate_bytes[142] = 23; + assign(test_msg_.certificate_bytes[153], 46); - test_msg.certificate_bytes[143] = 90; + assign(test_msg_.certificate_bytes[154], 25); - test_msg.certificate_bytes[144] = 94; + assign(test_msg_.certificate_bytes[155], 252); - test_msg.certificate_bytes[145] = 136; + assign(test_msg_.certificate_bytes[156], 229); - test_msg.certificate_bytes[146] = 6; + assign(test_msg_.certificate_bytes[157], 80); - test_msg.certificate_bytes[147] = 125; + assign(test_msg_.certificate_bytes[158], 143); - test_msg.certificate_bytes[148] = 91; + assign(test_msg_.certificate_bytes[159], 58); - test_msg.certificate_bytes[149] = 255; + assign(test_msg_.certificate_bytes[160], 241); - test_msg.certificate_bytes[150] = 15; + assign(test_msg_.certificate_bytes[161], 11); - test_msg.certificate_bytes[151] = 71; + assign(test_msg_.certificate_bytes[162], 62); - test_msg.certificate_bytes[152] = 43; + assign(test_msg_.certificate_bytes[163], 181); - test_msg.certificate_bytes[153] = 46; + assign(test_msg_.certificate_bytes[164], 155); - test_msg.certificate_bytes[154] = 25; + assign(test_msg_.certificate_bytes[165], 53); - test_msg.certificate_bytes[155] = 252; + assign(test_msg_.certificate_bytes[166], 153); - test_msg.certificate_bytes[156] = 229; + assign(test_msg_.certificate_bytes[167], 149); - test_msg.certificate_bytes[157] = 80; + assign(test_msg_.certificate_bytes[168], 152); - test_msg.certificate_bytes[158] = 143; + assign(test_msg_.certificate_bytes[169], 227); - test_msg.certificate_bytes[159] = 58; + assign(test_msg_.certificate_bytes[170], 150); - test_msg.certificate_bytes[160] = 241; + assign(test_msg_.certificate_bytes[171], 87); - test_msg.certificate_bytes[161] = 11; + assign(test_msg_.certificate_bytes[172], 112); - test_msg.certificate_bytes[162] = 62; + assign(test_msg_.certificate_bytes[173], 165); - test_msg.certificate_bytes[163] = 181; + assign(test_msg_.certificate_bytes[174], 2); - test_msg.certificate_bytes[164] = 155; + assign(test_msg_.certificate_bytes[175], 128); - test_msg.certificate_bytes[165] = 53; + assign(test_msg_.certificate_bytes[176], 231); - test_msg.certificate_bytes[166] = 153; + assign(test_msg_.certificate_bytes[177], 25); - test_msg.certificate_bytes[167] = 149; + assign(test_msg_.certificate_bytes[178], 157); - test_msg.certificate_bytes[168] = 152; + assign(test_msg_.certificate_bytes[179], 244); - test_msg.certificate_bytes[169] = 227; + assign(test_msg_.certificate_bytes[180], 204); - test_msg.certificate_bytes[170] = 150; + assign(test_msg_.certificate_bytes[181], 108); - test_msg.certificate_bytes[171] = 87; + assign(test_msg_.certificate_bytes[182], 253); - test_msg.certificate_bytes[172] = 112; + assign(test_msg_.certificate_bytes[183], 127); - test_msg.certificate_bytes[173] = 165; + assign(test_msg_.certificate_bytes[184], 122); - test_msg.certificate_bytes[174] = 2; + assign(test_msg_.certificate_bytes[185], 145); - test_msg.certificate_bytes[175] = 128; + assign(test_msg_.certificate_bytes[186], 113); - test_msg.certificate_bytes[176] = 231; + assign(test_msg_.certificate_bytes[187], 162); - test_msg.certificate_bytes[177] = 25; + assign(test_msg_.certificate_bytes[188], 197); - test_msg.certificate_bytes[178] = 157; + assign(test_msg_.certificate_bytes[189], 171); - test_msg.certificate_bytes[179] = 244; + assign(test_msg_.certificate_bytes[190], 199); - test_msg.certificate_bytes[180] = 204; + assign(test_msg_.certificate_bytes[191], 54); - test_msg.certificate_bytes[181] = 108; + assign(test_msg_.certificate_bytes[192], 184); - test_msg.certificate_bytes[182] = 253; + assign(test_msg_.certificate_bytes[193], 222); - test_msg.certificate_bytes[183] = 127; + assign(test_msg_.certificate_bytes[194], 206); - test_msg.certificate_bytes[184] = 122; + assign(test_msg_.certificate_bytes[195], 67); - test_msg.certificate_bytes[185] = 145; + assign(test_msg_.certificate_bytes[196], 144); - test_msg.certificate_bytes[186] = 113; + assign(test_msg_.certificate_bytes[197], 78); - test_msg.certificate_bytes[187] = 162; + assign(test_msg_.certificate_bytes[198], 187); - test_msg.certificate_bytes[188] = 197; + assign(test_msg_.certificate_bytes[199], 207); - test_msg.certificate_bytes[189] = 171; + assign(test_msg_.certificate_bytes[200], 60); - test_msg.certificate_bytes[190] = 199; + assign(test_msg_.certificate_bytes[201], 211); - test_msg.certificate_bytes[191] = 54; + assign(test_msg_.certificate_bytes[202], 141); - test_msg.certificate_bytes[192] = 184; + assign(test_msg_.certificate_bytes[203], 135); - test_msg.certificate_bytes[193] = 222; + assign(test_msg_.certificate_bytes[204], 106); - test_msg.certificate_bytes[194] = 206; + assign(test_msg_.certificate_bytes[205], 220); - test_msg.certificate_bytes[195] = 67; + assign(test_msg_.certificate_bytes[206], 79); - test_msg.certificate_bytes[196] = 144; + assign(test_msg_.certificate_bytes[207], 183); - test_msg.certificate_bytes[197] = 78; + assign(test_msg_.certificate_bytes[208], 245); - test_msg.certificate_bytes[198] = 187; + assign(test_msg_.certificate_bytes[209], 21); - test_msg.certificate_bytes[199] = 207; + assign(test_msg_.certificate_bytes[210], 161); - test_msg.certificate_bytes[200] = 60; + assign(test_msg_.certificate_bytes[211], 168); - test_msg.certificate_bytes[201] = 211; + assign(test_msg_.certificate_bytes[212], 34); - test_msg.certificate_bytes[202] = 141; + assign(test_msg_.certificate_bytes[213], 129); - test_msg.certificate_bytes[203] = 135; + assign(test_msg_.certificate_bytes[214], 50); - test_msg.certificate_bytes[204] = 106; + assign(test_msg_.certificate_bytes[215], 176); - test_msg.certificate_bytes[205] = 220; + assign(test_msg_.certificate_bytes[216], 1); - test_msg.certificate_bytes[206] = 79; + assign(test_msg_.certificate_bytes[217], 218); - test_msg.certificate_bytes[207] = 183; + assign(test_msg_.certificate_bytes[218], 20); - test_msg.certificate_bytes[208] = 245; + assign(test_msg_.certificate_bytes[219], 130); - test_msg.certificate_bytes[209] = 21; + assign(test_msg_.certificate_bytes[220], 59); - test_msg.certificate_bytes[210] = 161; + assign(test_msg_.certificate_bytes[221], 249); - test_msg.certificate_bytes[211] = 168; + assign(test_msg_.certificate_bytes[222], 109); - test_msg.certificate_bytes[212] = 34; + assign(test_msg_.certificate_bytes[223], 219); - test_msg.certificate_bytes[213] = 129; + assign(test_msg_.certificate_bytes[224], 0); - test_msg.certificate_bytes[214] = 50; + assign(test_msg_.certificate_bytes[225], 100); - test_msg.certificate_bytes[215] = 176; + assign(test_msg_.certificate_bytes[226], 103); - test_msg.certificate_bytes[216] = 1; + assign(test_msg_.certificate_bytes[227], 55); - test_msg.certificate_bytes[217] = 218; + assign(test_msg_.certificate_bytes[228], 29); - test_msg.certificate_bytes[218] = 20; + assign(test_msg_.certificate_bytes[229], 242); - test_msg.certificate_bytes[219] = 130; + assign(test_msg_.certificate_bytes[230], 110); - test_msg.certificate_bytes[220] = 59; + assign(test_msg_.certificate_bytes[231], 154); - test_msg.certificate_bytes[221] = 249; + assign(test_msg_.certificate_bytes[232], 190); - test_msg.certificate_bytes[222] = 109; + assign(test_msg_.certificate_bytes[233], 233); - test_msg.certificate_bytes[223] = 219; + assign(test_msg_.certificate_bytes[234], 142); - test_msg.certificate_bytes[224] = 0; + assign(test_msg_.certificate_bytes[235], 45); - test_msg.certificate_bytes[225] = 100; + assign(test_msg_.certificate_bytes[236], 61); - test_msg.certificate_bytes[226] = 103; + assign(test_msg_.certificate_bytes[237], 215); - test_msg.certificate_bytes[227] = 55; + assign(test_msg_.certificate_bytes[238], 202); - test_msg.certificate_bytes[228] = 29; + assign(test_msg_.certificate_bytes[239], 238); - test_msg.certificate_bytes[229] = 242; + assign(test_msg_.certificate_bytes[240], 88); - test_msg.certificate_bytes[230] = 110; + assign(test_msg_.certificate_bytes[241], 209); - test_msg.certificate_bytes[231] = 154; + assign(test_msg_.certificate_bytes[242], 70); - test_msg.certificate_bytes[232] = 190; + assign(test_msg_.certificate_bytes[243], 63); + + assign(test_msg_.certificate_bytes[244], 151); + + assign(test_msg_.certificate_bytes[245], 27); + + assign(test_msg_.certificate_bytes[246], 102); + + assign(test_msg_.certificate_id[0], 10); + + assign(test_msg_.certificate_id[1], 11); + + assign(test_msg_.certificate_id[2], 12); + + assign(test_msg_.certificate_id[3], 13); + assign(test_msg_.flags, 2); + assign(test_msg_.n_certificate_bytes, 247); + assign(test_msg_.n_msg, 48); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_certificate_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ecdsa_certificate_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEcdsaCertificate, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_certificate_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEcdsaCertificate); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ecdsa_certificate, + sizeof(msg->ecdsa_certificate)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ecdsa_certificate_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ecdsa_certificate, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEcdsaCertificate); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x1EDB; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 253; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_ecdsa_certificate_t &lesser, + const sbp_msg_ecdsa_certificate_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ecdsa_certificate_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ecdsa_certificate_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ecdsa_certificate_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ecdsa_certificate_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaCertificate, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaCertificate, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEcdsaCertificate, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEcdsaCertificate, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } - test_msg.certificate_bytes[233] = 233; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } - test_msg.certificate_bytes[234] = 142; + private: + sbp_msg_ecdsa_certificate_t test_msg_{}; + uint8_t encoded_frame_[253 + 8] = { + 85, 4, 12, 66, 0, 253, 48, 10, 11, 12, 13, 2, 180, 160, 116, + 77, 243, 28, 173, 36, 86, 33, 8, 31, 120, 73, 64, 169, 148, 224, + 57, 95, 17, 40, 213, 92, 195, 146, 235, 228, 177, 101, 82, 182, 25, + 172, 170, 250, 236, 7, 119, 4, 201, 10, 14, 208, 47, 126, 49, 210, + 174, 75, 221, 203, 24, 66, 52, 35, 26, 30, 140, 111, 246, 39, 226, + 205, 198, 178, 196, 5, 81, 9, 44, 164, 163, 214, 138, 123, 76, 74, + 237, 121, 13, 137, 186, 97, 193, 189, 200, 124, 69, 115, 230, 159, 185, + 158, 51, 12, 225, 65, 192, 105, 56, 41, 85, 133, 19, 217, 166, 48, + 139, 131, 96, 216, 98, 147, 132, 234, 167, 248, 247, 32, 239, 194, 188, + 254, 114, 117, 83, 25, 251, 191, 104, 240, 118, 68, 42, 93, 18, 16, + 37, 232, 99, 179, 23, 90, 94, 136, 6, 125, 91, 255, 15, 71, 43, + 46, 25, 252, 229, 80, 143, 58, 241, 11, 62, 181, 155, 53, 153, 149, + 152, 227, 150, 87, 112, 165, 2, 128, 231, 25, 157, 244, 204, 108, 253, + 127, 122, 145, 113, 162, 197, 171, 199, 54, 184, 222, 206, 67, 144, 78, + 187, 207, 60, 211, 141, 135, 106, 220, 79, 183, 245, 21, 161, 168, 34, + 129, 50, 176, 1, 218, 20, 130, 59, 249, 109, 219, 0, 100, 103, 55, + 29, 242, 110, 154, 190, 233, 142, 45, 61, 215, 202, 238, 88, 209, 70, + 63, 151, 27, 102, 219, 30, + }; + uint8_t encoded_payload_[253] = { + 48, 10, 11, 12, 13, 2, 180, 160, 116, 77, 243, 28, 173, 36, 86, + 33, 8, 31, 120, 73, 64, 169, 148, 224, 57, 95, 17, 40, 213, 92, + 195, 146, 235, 228, 177, 101, 82, 182, 25, 172, 170, 250, 236, 7, 119, + 4, 201, 10, 14, 208, 47, 126, 49, 210, 174, 75, 221, 203, 24, 66, + 52, 35, 26, 30, 140, 111, 246, 39, 226, 205, 198, 178, 196, 5, 81, + 9, 44, 164, 163, 214, 138, 123, 76, 74, 237, 121, 13, 137, 186, 97, + 193, 189, 200, 124, 69, 115, 230, 159, 185, 158, 51, 12, 225, 65, 192, + 105, 56, 41, 85, 133, 19, 217, 166, 48, 139, 131, 96, 216, 98, 147, + 132, 234, 167, 248, 247, 32, 239, 194, 188, 254, 114, 117, 83, 25, 251, + 191, 104, 240, 118, 68, 42, 93, 18, 16, 37, 232, 99, 179, 23, 90, + 94, 136, 6, 125, 91, 255, 15, 71, 43, 46, 25, 252, 229, 80, 143, + 58, 241, 11, 62, 181, 155, 53, 153, 149, 152, 227, 150, 87, 112, 165, + 2, 128, 231, 25, 157, 244, 204, 108, 253, 127, 122, 145, 113, 162, 197, + 171, 199, 54, 184, 222, 206, 67, 144, 78, 187, 207, 60, 211, 141, 135, + 106, 220, 79, 183, 245, 21, 161, 168, 34, 129, 50, 176, 1, 218, 20, + 130, 59, 249, 109, 219, 0, 100, 103, 55, 29, 242, 110, 154, 190, 233, + 142, 45, 61, 215, 202, 238, 88, 209, 70, 63, 151, 27, 102, + }; +}; - test_msg.certificate_bytes[235] = 45; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ecdsa_certificate_encoded_len(&info.test_msg), + info.payload_len); - test_msg.certificate_bytes[236] = 61; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEcdsaCertificate, &info.test_msg_wrapped), + info.payload_len); +} - test_msg.certificate_bytes[237] = 215; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[253]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ecdsa_certificate_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 253); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 253), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEcdsaCertificate, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 253); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 253), 0); +} - test_msg.certificate_bytes[238] = 202; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[253]; - test_msg.certificate_bytes[239] = 238; + EXPECT_EQ(sbp_msg_ecdsa_certificate_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 253), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[253]; + + for (uint8_t i = 0; i < 253; i++) { + EXPECT_EQ( + sbp_msg_ecdsa_certificate_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.certificate_bytes[240] = 88; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_certificate_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ecdsa_certificate_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 253); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEcdsaCertificate, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 253); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.certificate_bytes[241] = 209; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_certificate_t msg{}; - test_msg.certificate_bytes[242] = 70; + EXPECT_EQ(sbp_msg_ecdsa_certificate_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_certificate_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ecdsa_certificate_t t{}; + return sbp_msg_ecdsa_certificate_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ecdsa_certificate_t t{}; + t.n_certificate_bytes = 1; + return sbp_msg_ecdsa_certificate_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ecdsa_certificate_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} - test_msg.certificate_bytes[243] = 63; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.certificate_bytes[244] = 151; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.certificate_bytes[245] = 27; + CHandler handler{&state}; - test_msg.certificate_bytes[246] = 102; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.certificate_id[0] = 10; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.certificate_id[1] = 11; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.certificate_id[2] = 12; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.certificate_id[3] = 13; - test_msg.flags = 2; - test_msg.n_certificate_bytes = 247; - test_msg.n_msg = 48; + EXPECT_EQ(sbp_msg_ecdsa_certificate_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - EXPECT_EQ(send_message(66, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.certificate_bytes[0], 180) - << "incorrect value for last_msg_.certificate_bytes[0], expected 180, is " - << last_msg_.certificate_bytes[0]; - EXPECT_EQ(last_msg_.certificate_bytes[1], 160) - << "incorrect value for last_msg_.certificate_bytes[1], expected 160, is " - << last_msg_.certificate_bytes[1]; - EXPECT_EQ(last_msg_.certificate_bytes[2], 116) - << "incorrect value for last_msg_.certificate_bytes[2], expected 116, is " - << last_msg_.certificate_bytes[2]; - EXPECT_EQ(last_msg_.certificate_bytes[3], 77) - << "incorrect value for last_msg_.certificate_bytes[3], expected 77, is " - << last_msg_.certificate_bytes[3]; - EXPECT_EQ(last_msg_.certificate_bytes[4], 243) - << "incorrect value for last_msg_.certificate_bytes[4], expected 243, is " - << last_msg_.certificate_bytes[4]; - EXPECT_EQ(last_msg_.certificate_bytes[5], 28) - << "incorrect value for last_msg_.certificate_bytes[5], expected 28, is " - << last_msg_.certificate_bytes[5]; - EXPECT_EQ(last_msg_.certificate_bytes[6], 173) - << "incorrect value for last_msg_.certificate_bytes[6], expected 173, is " - << last_msg_.certificate_bytes[6]; - EXPECT_EQ(last_msg_.certificate_bytes[7], 36) - << "incorrect value for last_msg_.certificate_bytes[7], expected 36, is " - << last_msg_.certificate_bytes[7]; - EXPECT_EQ(last_msg_.certificate_bytes[8], 86) - << "incorrect value for last_msg_.certificate_bytes[8], expected 86, is " - << last_msg_.certificate_bytes[8]; - EXPECT_EQ(last_msg_.certificate_bytes[9], 33) - << "incorrect value for last_msg_.certificate_bytes[9], expected 33, is " - << last_msg_.certificate_bytes[9]; - EXPECT_EQ(last_msg_.certificate_bytes[10], 8) - << "incorrect value for last_msg_.certificate_bytes[10], expected 8, is " - << last_msg_.certificate_bytes[10]; - EXPECT_EQ(last_msg_.certificate_bytes[11], 31) - << "incorrect value for last_msg_.certificate_bytes[11], expected 31, is " - << last_msg_.certificate_bytes[11]; - EXPECT_EQ(last_msg_.certificate_bytes[12], 120) - << "incorrect value for last_msg_.certificate_bytes[12], expected 120, " - "is " - << last_msg_.certificate_bytes[12]; - EXPECT_EQ(last_msg_.certificate_bytes[13], 73) - << "incorrect value for last_msg_.certificate_bytes[13], expected 73, is " - << last_msg_.certificate_bytes[13]; - EXPECT_EQ(last_msg_.certificate_bytes[14], 64) - << "incorrect value for last_msg_.certificate_bytes[14], expected 64, is " - << last_msg_.certificate_bytes[14]; - EXPECT_EQ(last_msg_.certificate_bytes[15], 169) - << "incorrect value for last_msg_.certificate_bytes[15], expected 169, " - "is " - << last_msg_.certificate_bytes[15]; - EXPECT_EQ(last_msg_.certificate_bytes[16], 148) - << "incorrect value for last_msg_.certificate_bytes[16], expected 148, " - "is " - << last_msg_.certificate_bytes[16]; - EXPECT_EQ(last_msg_.certificate_bytes[17], 224) - << "incorrect value for last_msg_.certificate_bytes[17], expected 224, " - "is " - << last_msg_.certificate_bytes[17]; - EXPECT_EQ(last_msg_.certificate_bytes[18], 57) - << "incorrect value for last_msg_.certificate_bytes[18], expected 57, is " - << last_msg_.certificate_bytes[18]; - EXPECT_EQ(last_msg_.certificate_bytes[19], 95) - << "incorrect value for last_msg_.certificate_bytes[19], expected 95, is " - << last_msg_.certificate_bytes[19]; - EXPECT_EQ(last_msg_.certificate_bytes[20], 17) - << "incorrect value for last_msg_.certificate_bytes[20], expected 17, is " - << last_msg_.certificate_bytes[20]; - EXPECT_EQ(last_msg_.certificate_bytes[21], 40) - << "incorrect value for last_msg_.certificate_bytes[21], expected 40, is " - << last_msg_.certificate_bytes[21]; - EXPECT_EQ(last_msg_.certificate_bytes[22], 213) - << "incorrect value for last_msg_.certificate_bytes[22], expected 213, " - "is " - << last_msg_.certificate_bytes[22]; - EXPECT_EQ(last_msg_.certificate_bytes[23], 92) - << "incorrect value for last_msg_.certificate_bytes[23], expected 92, is " - << last_msg_.certificate_bytes[23]; - EXPECT_EQ(last_msg_.certificate_bytes[24], 195) - << "incorrect value for last_msg_.certificate_bytes[24], expected 195, " - "is " - << last_msg_.certificate_bytes[24]; - EXPECT_EQ(last_msg_.certificate_bytes[25], 146) - << "incorrect value for last_msg_.certificate_bytes[25], expected 146, " - "is " - << last_msg_.certificate_bytes[25]; - EXPECT_EQ(last_msg_.certificate_bytes[26], 235) - << "incorrect value for last_msg_.certificate_bytes[26], expected 235, " - "is " - << last_msg_.certificate_bytes[26]; - EXPECT_EQ(last_msg_.certificate_bytes[27], 228) - << "incorrect value for last_msg_.certificate_bytes[27], expected 228, " - "is " - << last_msg_.certificate_bytes[27]; - EXPECT_EQ(last_msg_.certificate_bytes[28], 177) - << "incorrect value for last_msg_.certificate_bytes[28], expected 177, " - "is " - << last_msg_.certificate_bytes[28]; - EXPECT_EQ(last_msg_.certificate_bytes[29], 101) - << "incorrect value for last_msg_.certificate_bytes[29], expected 101, " - "is " - << last_msg_.certificate_bytes[29]; - EXPECT_EQ(last_msg_.certificate_bytes[30], 82) - << "incorrect value for last_msg_.certificate_bytes[30], expected 82, is " - << last_msg_.certificate_bytes[30]; - EXPECT_EQ(last_msg_.certificate_bytes[31], 182) - << "incorrect value for last_msg_.certificate_bytes[31], expected 182, " - "is " - << last_msg_.certificate_bytes[31]; - EXPECT_EQ(last_msg_.certificate_bytes[32], 25) - << "incorrect value for last_msg_.certificate_bytes[32], expected 25, is " - << last_msg_.certificate_bytes[32]; - EXPECT_EQ(last_msg_.certificate_bytes[33], 172) - << "incorrect value for last_msg_.certificate_bytes[33], expected 172, " - "is " - << last_msg_.certificate_bytes[33]; - EXPECT_EQ(last_msg_.certificate_bytes[34], 170) - << "incorrect value for last_msg_.certificate_bytes[34], expected 170, " - "is " - << last_msg_.certificate_bytes[34]; - EXPECT_EQ(last_msg_.certificate_bytes[35], 250) - << "incorrect value for last_msg_.certificate_bytes[35], expected 250, " - "is " - << last_msg_.certificate_bytes[35]; - EXPECT_EQ(last_msg_.certificate_bytes[36], 236) - << "incorrect value for last_msg_.certificate_bytes[36], expected 236, " - "is " - << last_msg_.certificate_bytes[36]; - EXPECT_EQ(last_msg_.certificate_bytes[37], 7) - << "incorrect value for last_msg_.certificate_bytes[37], expected 7, is " - << last_msg_.certificate_bytes[37]; - EXPECT_EQ(last_msg_.certificate_bytes[38], 119) - << "incorrect value for last_msg_.certificate_bytes[38], expected 119, " - "is " - << last_msg_.certificate_bytes[38]; - EXPECT_EQ(last_msg_.certificate_bytes[39], 4) - << "incorrect value for last_msg_.certificate_bytes[39], expected 4, is " - << last_msg_.certificate_bytes[39]; - EXPECT_EQ(last_msg_.certificate_bytes[40], 201) - << "incorrect value for last_msg_.certificate_bytes[40], expected 201, " - "is " - << last_msg_.certificate_bytes[40]; - EXPECT_EQ(last_msg_.certificate_bytes[41], 10) - << "incorrect value for last_msg_.certificate_bytes[41], expected 10, is " - << last_msg_.certificate_bytes[41]; - EXPECT_EQ(last_msg_.certificate_bytes[42], 14) - << "incorrect value for last_msg_.certificate_bytes[42], expected 14, is " - << last_msg_.certificate_bytes[42]; - EXPECT_EQ(last_msg_.certificate_bytes[43], 208) - << "incorrect value for last_msg_.certificate_bytes[43], expected 208, " - "is " - << last_msg_.certificate_bytes[43]; - EXPECT_EQ(last_msg_.certificate_bytes[44], 47) - << "incorrect value for last_msg_.certificate_bytes[44], expected 47, is " - << last_msg_.certificate_bytes[44]; - EXPECT_EQ(last_msg_.certificate_bytes[45], 126) - << "incorrect value for last_msg_.certificate_bytes[45], expected 126, " - "is " - << last_msg_.certificate_bytes[45]; - EXPECT_EQ(last_msg_.certificate_bytes[46], 49) - << "incorrect value for last_msg_.certificate_bytes[46], expected 49, is " - << last_msg_.certificate_bytes[46]; - EXPECT_EQ(last_msg_.certificate_bytes[47], 210) - << "incorrect value for last_msg_.certificate_bytes[47], expected 210, " - "is " - << last_msg_.certificate_bytes[47]; - EXPECT_EQ(last_msg_.certificate_bytes[48], 174) - << "incorrect value for last_msg_.certificate_bytes[48], expected 174, " - "is " - << last_msg_.certificate_bytes[48]; - EXPECT_EQ(last_msg_.certificate_bytes[49], 75) - << "incorrect value for last_msg_.certificate_bytes[49], expected 75, is " - << last_msg_.certificate_bytes[49]; - EXPECT_EQ(last_msg_.certificate_bytes[50], 221) - << "incorrect value for last_msg_.certificate_bytes[50], expected 221, " - "is " - << last_msg_.certificate_bytes[50]; - EXPECT_EQ(last_msg_.certificate_bytes[51], 203) - << "incorrect value for last_msg_.certificate_bytes[51], expected 203, " - "is " - << last_msg_.certificate_bytes[51]; - EXPECT_EQ(last_msg_.certificate_bytes[52], 24) - << "incorrect value for last_msg_.certificate_bytes[52], expected 24, is " - << last_msg_.certificate_bytes[52]; - EXPECT_EQ(last_msg_.certificate_bytes[53], 66) - << "incorrect value for last_msg_.certificate_bytes[53], expected 66, is " - << last_msg_.certificate_bytes[53]; - EXPECT_EQ(last_msg_.certificate_bytes[54], 52) - << "incorrect value for last_msg_.certificate_bytes[54], expected 52, is " - << last_msg_.certificate_bytes[54]; - EXPECT_EQ(last_msg_.certificate_bytes[55], 35) - << "incorrect value for last_msg_.certificate_bytes[55], expected 35, is " - << last_msg_.certificate_bytes[55]; - EXPECT_EQ(last_msg_.certificate_bytes[56], 26) - << "incorrect value for last_msg_.certificate_bytes[56], expected 26, is " - << last_msg_.certificate_bytes[56]; - EXPECT_EQ(last_msg_.certificate_bytes[57], 30) - << "incorrect value for last_msg_.certificate_bytes[57], expected 30, is " - << last_msg_.certificate_bytes[57]; - EXPECT_EQ(last_msg_.certificate_bytes[58], 140) - << "incorrect value for last_msg_.certificate_bytes[58], expected 140, " - "is " - << last_msg_.certificate_bytes[58]; - EXPECT_EQ(last_msg_.certificate_bytes[59], 111) - << "incorrect value for last_msg_.certificate_bytes[59], expected 111, " - "is " - << last_msg_.certificate_bytes[59]; - EXPECT_EQ(last_msg_.certificate_bytes[60], 246) - << "incorrect value for last_msg_.certificate_bytes[60], expected 246, " - "is " - << last_msg_.certificate_bytes[60]; - EXPECT_EQ(last_msg_.certificate_bytes[61], 39) - << "incorrect value for last_msg_.certificate_bytes[61], expected 39, is " - << last_msg_.certificate_bytes[61]; - EXPECT_EQ(last_msg_.certificate_bytes[62], 226) - << "incorrect value for last_msg_.certificate_bytes[62], expected 226, " - "is " - << last_msg_.certificate_bytes[62]; - EXPECT_EQ(last_msg_.certificate_bytes[63], 205) - << "incorrect value for last_msg_.certificate_bytes[63], expected 205, " - "is " - << last_msg_.certificate_bytes[63]; - EXPECT_EQ(last_msg_.certificate_bytes[64], 198) - << "incorrect value for last_msg_.certificate_bytes[64], expected 198, " - "is " - << last_msg_.certificate_bytes[64]; - EXPECT_EQ(last_msg_.certificate_bytes[65], 178) - << "incorrect value for last_msg_.certificate_bytes[65], expected 178, " - "is " - << last_msg_.certificate_bytes[65]; - EXPECT_EQ(last_msg_.certificate_bytes[66], 196) - << "incorrect value for last_msg_.certificate_bytes[66], expected 196, " - "is " - << last_msg_.certificate_bytes[66]; - EXPECT_EQ(last_msg_.certificate_bytes[67], 5) - << "incorrect value for last_msg_.certificate_bytes[67], expected 5, is " - << last_msg_.certificate_bytes[67]; - EXPECT_EQ(last_msg_.certificate_bytes[68], 81) - << "incorrect value for last_msg_.certificate_bytes[68], expected 81, is " - << last_msg_.certificate_bytes[68]; - EXPECT_EQ(last_msg_.certificate_bytes[69], 9) - << "incorrect value for last_msg_.certificate_bytes[69], expected 9, is " - << last_msg_.certificate_bytes[69]; - EXPECT_EQ(last_msg_.certificate_bytes[70], 44) - << "incorrect value for last_msg_.certificate_bytes[70], expected 44, is " - << last_msg_.certificate_bytes[70]; - EXPECT_EQ(last_msg_.certificate_bytes[71], 164) - << "incorrect value for last_msg_.certificate_bytes[71], expected 164, " - "is " - << last_msg_.certificate_bytes[71]; - EXPECT_EQ(last_msg_.certificate_bytes[72], 163) - << "incorrect value for last_msg_.certificate_bytes[72], expected 163, " - "is " - << last_msg_.certificate_bytes[72]; - EXPECT_EQ(last_msg_.certificate_bytes[73], 214) - << "incorrect value for last_msg_.certificate_bytes[73], expected 214, " - "is " - << last_msg_.certificate_bytes[73]; - EXPECT_EQ(last_msg_.certificate_bytes[74], 138) - << "incorrect value for last_msg_.certificate_bytes[74], expected 138, " - "is " - << last_msg_.certificate_bytes[74]; - EXPECT_EQ(last_msg_.certificate_bytes[75], 123) - << "incorrect value for last_msg_.certificate_bytes[75], expected 123, " - "is " - << last_msg_.certificate_bytes[75]; - EXPECT_EQ(last_msg_.certificate_bytes[76], 76) - << "incorrect value for last_msg_.certificate_bytes[76], expected 76, is " - << last_msg_.certificate_bytes[76]; - EXPECT_EQ(last_msg_.certificate_bytes[77], 74) - << "incorrect value for last_msg_.certificate_bytes[77], expected 74, is " - << last_msg_.certificate_bytes[77]; - EXPECT_EQ(last_msg_.certificate_bytes[78], 237) - << "incorrect value for last_msg_.certificate_bytes[78], expected 237, " - "is " - << last_msg_.certificate_bytes[78]; - EXPECT_EQ(last_msg_.certificate_bytes[79], 121) - << "incorrect value for last_msg_.certificate_bytes[79], expected 121, " - "is " - << last_msg_.certificate_bytes[79]; - EXPECT_EQ(last_msg_.certificate_bytes[80], 13) - << "incorrect value for last_msg_.certificate_bytes[80], expected 13, is " - << last_msg_.certificate_bytes[80]; - EXPECT_EQ(last_msg_.certificate_bytes[81], 137) - << "incorrect value for last_msg_.certificate_bytes[81], expected 137, " - "is " - << last_msg_.certificate_bytes[81]; - EXPECT_EQ(last_msg_.certificate_bytes[82], 186) - << "incorrect value for last_msg_.certificate_bytes[82], expected 186, " - "is " - << last_msg_.certificate_bytes[82]; - EXPECT_EQ(last_msg_.certificate_bytes[83], 97) - << "incorrect value for last_msg_.certificate_bytes[83], expected 97, is " - << last_msg_.certificate_bytes[83]; - EXPECT_EQ(last_msg_.certificate_bytes[84], 193) - << "incorrect value for last_msg_.certificate_bytes[84], expected 193, " - "is " - << last_msg_.certificate_bytes[84]; - EXPECT_EQ(last_msg_.certificate_bytes[85], 189) - << "incorrect value for last_msg_.certificate_bytes[85], expected 189, " - "is " - << last_msg_.certificate_bytes[85]; - EXPECT_EQ(last_msg_.certificate_bytes[86], 200) - << "incorrect value for last_msg_.certificate_bytes[86], expected 200, " - "is " - << last_msg_.certificate_bytes[86]; - EXPECT_EQ(last_msg_.certificate_bytes[87], 124) - << "incorrect value for last_msg_.certificate_bytes[87], expected 124, " - "is " - << last_msg_.certificate_bytes[87]; - EXPECT_EQ(last_msg_.certificate_bytes[88], 69) - << "incorrect value for last_msg_.certificate_bytes[88], expected 69, is " - << last_msg_.certificate_bytes[88]; - EXPECT_EQ(last_msg_.certificate_bytes[89], 115) - << "incorrect value for last_msg_.certificate_bytes[89], expected 115, " - "is " - << last_msg_.certificate_bytes[89]; - EXPECT_EQ(last_msg_.certificate_bytes[90], 230) - << "incorrect value for last_msg_.certificate_bytes[90], expected 230, " - "is " - << last_msg_.certificate_bytes[90]; - EXPECT_EQ(last_msg_.certificate_bytes[91], 159) - << "incorrect value for last_msg_.certificate_bytes[91], expected 159, " - "is " - << last_msg_.certificate_bytes[91]; - EXPECT_EQ(last_msg_.certificate_bytes[92], 185) - << "incorrect value for last_msg_.certificate_bytes[92], expected 185, " - "is " - << last_msg_.certificate_bytes[92]; - EXPECT_EQ(last_msg_.certificate_bytes[93], 158) - << "incorrect value for last_msg_.certificate_bytes[93], expected 158, " - "is " - << last_msg_.certificate_bytes[93]; - EXPECT_EQ(last_msg_.certificate_bytes[94], 51) - << "incorrect value for last_msg_.certificate_bytes[94], expected 51, is " - << last_msg_.certificate_bytes[94]; - EXPECT_EQ(last_msg_.certificate_bytes[95], 12) - << "incorrect value for last_msg_.certificate_bytes[95], expected 12, is " - << last_msg_.certificate_bytes[95]; - EXPECT_EQ(last_msg_.certificate_bytes[96], 225) - << "incorrect value for last_msg_.certificate_bytes[96], expected 225, " - "is " - << last_msg_.certificate_bytes[96]; - EXPECT_EQ(last_msg_.certificate_bytes[97], 65) - << "incorrect value for last_msg_.certificate_bytes[97], expected 65, is " - << last_msg_.certificate_bytes[97]; - EXPECT_EQ(last_msg_.certificate_bytes[98], 192) - << "incorrect value for last_msg_.certificate_bytes[98], expected 192, " - "is " - << last_msg_.certificate_bytes[98]; - EXPECT_EQ(last_msg_.certificate_bytes[99], 105) - << "incorrect value for last_msg_.certificate_bytes[99], expected 105, " - "is " - << last_msg_.certificate_bytes[99]; - EXPECT_EQ(last_msg_.certificate_bytes[100], 56) - << "incorrect value for last_msg_.certificate_bytes[100], expected 56, " - "is " - << last_msg_.certificate_bytes[100]; - EXPECT_EQ(last_msg_.certificate_bytes[101], 41) - << "incorrect value for last_msg_.certificate_bytes[101], expected 41, " - "is " - << last_msg_.certificate_bytes[101]; - EXPECT_EQ(last_msg_.certificate_bytes[102], 85) - << "incorrect value for last_msg_.certificate_bytes[102], expected 85, " - "is " - << last_msg_.certificate_bytes[102]; - EXPECT_EQ(last_msg_.certificate_bytes[103], 133) - << "incorrect value for last_msg_.certificate_bytes[103], expected 133, " - "is " - << last_msg_.certificate_bytes[103]; - EXPECT_EQ(last_msg_.certificate_bytes[104], 19) - << "incorrect value for last_msg_.certificate_bytes[104], expected 19, " - "is " - << last_msg_.certificate_bytes[104]; - EXPECT_EQ(last_msg_.certificate_bytes[105], 217) - << "incorrect value for last_msg_.certificate_bytes[105], expected 217, " - "is " - << last_msg_.certificate_bytes[105]; - EXPECT_EQ(last_msg_.certificate_bytes[106], 166) - << "incorrect value for last_msg_.certificate_bytes[106], expected 166, " - "is " - << last_msg_.certificate_bytes[106]; - EXPECT_EQ(last_msg_.certificate_bytes[107], 48) - << "incorrect value for last_msg_.certificate_bytes[107], expected 48, " - "is " - << last_msg_.certificate_bytes[107]; - EXPECT_EQ(last_msg_.certificate_bytes[108], 139) - << "incorrect value for last_msg_.certificate_bytes[108], expected 139, " - "is " - << last_msg_.certificate_bytes[108]; - EXPECT_EQ(last_msg_.certificate_bytes[109], 131) - << "incorrect value for last_msg_.certificate_bytes[109], expected 131, " - "is " - << last_msg_.certificate_bytes[109]; - EXPECT_EQ(last_msg_.certificate_bytes[110], 96) - << "incorrect value for last_msg_.certificate_bytes[110], expected 96, " - "is " - << last_msg_.certificate_bytes[110]; - EXPECT_EQ(last_msg_.certificate_bytes[111], 216) - << "incorrect value for last_msg_.certificate_bytes[111], expected 216, " - "is " - << last_msg_.certificate_bytes[111]; - EXPECT_EQ(last_msg_.certificate_bytes[112], 98) - << "incorrect value for last_msg_.certificate_bytes[112], expected 98, " - "is " - << last_msg_.certificate_bytes[112]; - EXPECT_EQ(last_msg_.certificate_bytes[113], 147) - << "incorrect value for last_msg_.certificate_bytes[113], expected 147, " - "is " - << last_msg_.certificate_bytes[113]; - EXPECT_EQ(last_msg_.certificate_bytes[114], 132) - << "incorrect value for last_msg_.certificate_bytes[114], expected 132, " - "is " - << last_msg_.certificate_bytes[114]; - EXPECT_EQ(last_msg_.certificate_bytes[115], 234) - << "incorrect value for last_msg_.certificate_bytes[115], expected 234, " - "is " - << last_msg_.certificate_bytes[115]; - EXPECT_EQ(last_msg_.certificate_bytes[116], 167) - << "incorrect value for last_msg_.certificate_bytes[116], expected 167, " - "is " - << last_msg_.certificate_bytes[116]; - EXPECT_EQ(last_msg_.certificate_bytes[117], 248) - << "incorrect value for last_msg_.certificate_bytes[117], expected 248, " - "is " - << last_msg_.certificate_bytes[117]; - EXPECT_EQ(last_msg_.certificate_bytes[118], 247) - << "incorrect value for last_msg_.certificate_bytes[118], expected 247, " - "is " - << last_msg_.certificate_bytes[118]; - EXPECT_EQ(last_msg_.certificate_bytes[119], 32) - << "incorrect value for last_msg_.certificate_bytes[119], expected 32, " - "is " - << last_msg_.certificate_bytes[119]; - EXPECT_EQ(last_msg_.certificate_bytes[120], 239) - << "incorrect value for last_msg_.certificate_bytes[120], expected 239, " - "is " - << last_msg_.certificate_bytes[120]; - EXPECT_EQ(last_msg_.certificate_bytes[121], 194) - << "incorrect value for last_msg_.certificate_bytes[121], expected 194, " - "is " - << last_msg_.certificate_bytes[121]; - EXPECT_EQ(last_msg_.certificate_bytes[122], 188) - << "incorrect value for last_msg_.certificate_bytes[122], expected 188, " - "is " - << last_msg_.certificate_bytes[122]; - EXPECT_EQ(last_msg_.certificate_bytes[123], 254) - << "incorrect value for last_msg_.certificate_bytes[123], expected 254, " - "is " - << last_msg_.certificate_bytes[123]; - EXPECT_EQ(last_msg_.certificate_bytes[124], 114) - << "incorrect value for last_msg_.certificate_bytes[124], expected 114, " - "is " - << last_msg_.certificate_bytes[124]; - EXPECT_EQ(last_msg_.certificate_bytes[125], 117) - << "incorrect value for last_msg_.certificate_bytes[125], expected 117, " - "is " - << last_msg_.certificate_bytes[125]; - EXPECT_EQ(last_msg_.certificate_bytes[126], 83) - << "incorrect value for last_msg_.certificate_bytes[126], expected 83, " - "is " - << last_msg_.certificate_bytes[126]; - EXPECT_EQ(last_msg_.certificate_bytes[127], 25) - << "incorrect value for last_msg_.certificate_bytes[127], expected 25, " - "is " - << last_msg_.certificate_bytes[127]; - EXPECT_EQ(last_msg_.certificate_bytes[128], 251) - << "incorrect value for last_msg_.certificate_bytes[128], expected 251, " - "is " - << last_msg_.certificate_bytes[128]; - EXPECT_EQ(last_msg_.certificate_bytes[129], 191) - << "incorrect value for last_msg_.certificate_bytes[129], expected 191, " - "is " - << last_msg_.certificate_bytes[129]; - EXPECT_EQ(last_msg_.certificate_bytes[130], 104) - << "incorrect value for last_msg_.certificate_bytes[130], expected 104, " - "is " - << last_msg_.certificate_bytes[130]; - EXPECT_EQ(last_msg_.certificate_bytes[131], 240) - << "incorrect value for last_msg_.certificate_bytes[131], expected 240, " - "is " - << last_msg_.certificate_bytes[131]; - EXPECT_EQ(last_msg_.certificate_bytes[132], 118) - << "incorrect value for last_msg_.certificate_bytes[132], expected 118, " - "is " - << last_msg_.certificate_bytes[132]; - EXPECT_EQ(last_msg_.certificate_bytes[133], 68) - << "incorrect value for last_msg_.certificate_bytes[133], expected 68, " - "is " - << last_msg_.certificate_bytes[133]; - EXPECT_EQ(last_msg_.certificate_bytes[134], 42) - << "incorrect value for last_msg_.certificate_bytes[134], expected 42, " - "is " - << last_msg_.certificate_bytes[134]; - EXPECT_EQ(last_msg_.certificate_bytes[135], 93) - << "incorrect value for last_msg_.certificate_bytes[135], expected 93, " - "is " - << last_msg_.certificate_bytes[135]; - EXPECT_EQ(last_msg_.certificate_bytes[136], 18) - << "incorrect value for last_msg_.certificate_bytes[136], expected 18, " - "is " - << last_msg_.certificate_bytes[136]; - EXPECT_EQ(last_msg_.certificate_bytes[137], 16) - << "incorrect value for last_msg_.certificate_bytes[137], expected 16, " - "is " - << last_msg_.certificate_bytes[137]; - EXPECT_EQ(last_msg_.certificate_bytes[138], 37) - << "incorrect value for last_msg_.certificate_bytes[138], expected 37, " - "is " - << last_msg_.certificate_bytes[138]; - EXPECT_EQ(last_msg_.certificate_bytes[139], 232) - << "incorrect value for last_msg_.certificate_bytes[139], expected 232, " - "is " - << last_msg_.certificate_bytes[139]; - EXPECT_EQ(last_msg_.certificate_bytes[140], 99) - << "incorrect value for last_msg_.certificate_bytes[140], expected 99, " - "is " - << last_msg_.certificate_bytes[140]; - EXPECT_EQ(last_msg_.certificate_bytes[141], 179) - << "incorrect value for last_msg_.certificate_bytes[141], expected 179, " - "is " - << last_msg_.certificate_bytes[141]; - EXPECT_EQ(last_msg_.certificate_bytes[142], 23) - << "incorrect value for last_msg_.certificate_bytes[142], expected 23, " - "is " - << last_msg_.certificate_bytes[142]; - EXPECT_EQ(last_msg_.certificate_bytes[143], 90) - << "incorrect value for last_msg_.certificate_bytes[143], expected 90, " - "is " - << last_msg_.certificate_bytes[143]; - EXPECT_EQ(last_msg_.certificate_bytes[144], 94) - << "incorrect value for last_msg_.certificate_bytes[144], expected 94, " - "is " - << last_msg_.certificate_bytes[144]; - EXPECT_EQ(last_msg_.certificate_bytes[145], 136) - << "incorrect value for last_msg_.certificate_bytes[145], expected 136, " - "is " - << last_msg_.certificate_bytes[145]; - EXPECT_EQ(last_msg_.certificate_bytes[146], 6) - << "incorrect value for last_msg_.certificate_bytes[146], expected 6, is " - << last_msg_.certificate_bytes[146]; - EXPECT_EQ(last_msg_.certificate_bytes[147], 125) - << "incorrect value for last_msg_.certificate_bytes[147], expected 125, " - "is " - << last_msg_.certificate_bytes[147]; - EXPECT_EQ(last_msg_.certificate_bytes[148], 91) - << "incorrect value for last_msg_.certificate_bytes[148], expected 91, " - "is " - << last_msg_.certificate_bytes[148]; - EXPECT_EQ(last_msg_.certificate_bytes[149], 255) - << "incorrect value for last_msg_.certificate_bytes[149], expected 255, " - "is " - << last_msg_.certificate_bytes[149]; - EXPECT_EQ(last_msg_.certificate_bytes[150], 15) - << "incorrect value for last_msg_.certificate_bytes[150], expected 15, " - "is " - << last_msg_.certificate_bytes[150]; - EXPECT_EQ(last_msg_.certificate_bytes[151], 71) - << "incorrect value for last_msg_.certificate_bytes[151], expected 71, " - "is " - << last_msg_.certificate_bytes[151]; - EXPECT_EQ(last_msg_.certificate_bytes[152], 43) - << "incorrect value for last_msg_.certificate_bytes[152], expected 43, " - "is " - << last_msg_.certificate_bytes[152]; - EXPECT_EQ(last_msg_.certificate_bytes[153], 46) - << "incorrect value for last_msg_.certificate_bytes[153], expected 46, " - "is " - << last_msg_.certificate_bytes[153]; - EXPECT_EQ(last_msg_.certificate_bytes[154], 25) - << "incorrect value for last_msg_.certificate_bytes[154], expected 25, " - "is " - << last_msg_.certificate_bytes[154]; - EXPECT_EQ(last_msg_.certificate_bytes[155], 252) - << "incorrect value for last_msg_.certificate_bytes[155], expected 252, " - "is " - << last_msg_.certificate_bytes[155]; - EXPECT_EQ(last_msg_.certificate_bytes[156], 229) - << "incorrect value for last_msg_.certificate_bytes[156], expected 229, " - "is " - << last_msg_.certificate_bytes[156]; - EXPECT_EQ(last_msg_.certificate_bytes[157], 80) - << "incorrect value for last_msg_.certificate_bytes[157], expected 80, " - "is " - << last_msg_.certificate_bytes[157]; - EXPECT_EQ(last_msg_.certificate_bytes[158], 143) - << "incorrect value for last_msg_.certificate_bytes[158], expected 143, " - "is " - << last_msg_.certificate_bytes[158]; - EXPECT_EQ(last_msg_.certificate_bytes[159], 58) - << "incorrect value for last_msg_.certificate_bytes[159], expected 58, " - "is " - << last_msg_.certificate_bytes[159]; - EXPECT_EQ(last_msg_.certificate_bytes[160], 241) - << "incorrect value for last_msg_.certificate_bytes[160], expected 241, " - "is " - << last_msg_.certificate_bytes[160]; - EXPECT_EQ(last_msg_.certificate_bytes[161], 11) - << "incorrect value for last_msg_.certificate_bytes[161], expected 11, " - "is " - << last_msg_.certificate_bytes[161]; - EXPECT_EQ(last_msg_.certificate_bytes[162], 62) - << "incorrect value for last_msg_.certificate_bytes[162], expected 62, " - "is " - << last_msg_.certificate_bytes[162]; - EXPECT_EQ(last_msg_.certificate_bytes[163], 181) - << "incorrect value for last_msg_.certificate_bytes[163], expected 181, " - "is " - << last_msg_.certificate_bytes[163]; - EXPECT_EQ(last_msg_.certificate_bytes[164], 155) - << "incorrect value for last_msg_.certificate_bytes[164], expected 155, " - "is " - << last_msg_.certificate_bytes[164]; - EXPECT_EQ(last_msg_.certificate_bytes[165], 53) - << "incorrect value for last_msg_.certificate_bytes[165], expected 53, " - "is " - << last_msg_.certificate_bytes[165]; - EXPECT_EQ(last_msg_.certificate_bytes[166], 153) - << "incorrect value for last_msg_.certificate_bytes[166], expected 153, " - "is " - << last_msg_.certificate_bytes[166]; - EXPECT_EQ(last_msg_.certificate_bytes[167], 149) - << "incorrect value for last_msg_.certificate_bytes[167], expected 149, " - "is " - << last_msg_.certificate_bytes[167]; - EXPECT_EQ(last_msg_.certificate_bytes[168], 152) - << "incorrect value for last_msg_.certificate_bytes[168], expected 152, " - "is " - << last_msg_.certificate_bytes[168]; - EXPECT_EQ(last_msg_.certificate_bytes[169], 227) - << "incorrect value for last_msg_.certificate_bytes[169], expected 227, " - "is " - << last_msg_.certificate_bytes[169]; - EXPECT_EQ(last_msg_.certificate_bytes[170], 150) - << "incorrect value for last_msg_.certificate_bytes[170], expected 150, " - "is " - << last_msg_.certificate_bytes[170]; - EXPECT_EQ(last_msg_.certificate_bytes[171], 87) - << "incorrect value for last_msg_.certificate_bytes[171], expected 87, " - "is " - << last_msg_.certificate_bytes[171]; - EXPECT_EQ(last_msg_.certificate_bytes[172], 112) - << "incorrect value for last_msg_.certificate_bytes[172], expected 112, " - "is " - << last_msg_.certificate_bytes[172]; - EXPECT_EQ(last_msg_.certificate_bytes[173], 165) - << "incorrect value for last_msg_.certificate_bytes[173], expected 165, " - "is " - << last_msg_.certificate_bytes[173]; - EXPECT_EQ(last_msg_.certificate_bytes[174], 2) - << "incorrect value for last_msg_.certificate_bytes[174], expected 2, is " - << last_msg_.certificate_bytes[174]; - EXPECT_EQ(last_msg_.certificate_bytes[175], 128) - << "incorrect value for last_msg_.certificate_bytes[175], expected 128, " - "is " - << last_msg_.certificate_bytes[175]; - EXPECT_EQ(last_msg_.certificate_bytes[176], 231) - << "incorrect value for last_msg_.certificate_bytes[176], expected 231, " - "is " - << last_msg_.certificate_bytes[176]; - EXPECT_EQ(last_msg_.certificate_bytes[177], 25) - << "incorrect value for last_msg_.certificate_bytes[177], expected 25, " - "is " - << last_msg_.certificate_bytes[177]; - EXPECT_EQ(last_msg_.certificate_bytes[178], 157) - << "incorrect value for last_msg_.certificate_bytes[178], expected 157, " - "is " - << last_msg_.certificate_bytes[178]; - EXPECT_EQ(last_msg_.certificate_bytes[179], 244) - << "incorrect value for last_msg_.certificate_bytes[179], expected 244, " - "is " - << last_msg_.certificate_bytes[179]; - EXPECT_EQ(last_msg_.certificate_bytes[180], 204) - << "incorrect value for last_msg_.certificate_bytes[180], expected 204, " - "is " - << last_msg_.certificate_bytes[180]; - EXPECT_EQ(last_msg_.certificate_bytes[181], 108) - << "incorrect value for last_msg_.certificate_bytes[181], expected 108, " - "is " - << last_msg_.certificate_bytes[181]; - EXPECT_EQ(last_msg_.certificate_bytes[182], 253) - << "incorrect value for last_msg_.certificate_bytes[182], expected 253, " - "is " - << last_msg_.certificate_bytes[182]; - EXPECT_EQ(last_msg_.certificate_bytes[183], 127) - << "incorrect value for last_msg_.certificate_bytes[183], expected 127, " - "is " - << last_msg_.certificate_bytes[183]; - EXPECT_EQ(last_msg_.certificate_bytes[184], 122) - << "incorrect value for last_msg_.certificate_bytes[184], expected 122, " - "is " - << last_msg_.certificate_bytes[184]; - EXPECT_EQ(last_msg_.certificate_bytes[185], 145) - << "incorrect value for last_msg_.certificate_bytes[185], expected 145, " - "is " - << last_msg_.certificate_bytes[185]; - EXPECT_EQ(last_msg_.certificate_bytes[186], 113) - << "incorrect value for last_msg_.certificate_bytes[186], expected 113, " - "is " - << last_msg_.certificate_bytes[186]; - EXPECT_EQ(last_msg_.certificate_bytes[187], 162) - << "incorrect value for last_msg_.certificate_bytes[187], expected 162, " - "is " - << last_msg_.certificate_bytes[187]; - EXPECT_EQ(last_msg_.certificate_bytes[188], 197) - << "incorrect value for last_msg_.certificate_bytes[188], expected 197, " - "is " - << last_msg_.certificate_bytes[188]; - EXPECT_EQ(last_msg_.certificate_bytes[189], 171) - << "incorrect value for last_msg_.certificate_bytes[189], expected 171, " - "is " - << last_msg_.certificate_bytes[189]; - EXPECT_EQ(last_msg_.certificate_bytes[190], 199) - << "incorrect value for last_msg_.certificate_bytes[190], expected 199, " - "is " - << last_msg_.certificate_bytes[190]; - EXPECT_EQ(last_msg_.certificate_bytes[191], 54) - << "incorrect value for last_msg_.certificate_bytes[191], expected 54, " - "is " - << last_msg_.certificate_bytes[191]; - EXPECT_EQ(last_msg_.certificate_bytes[192], 184) - << "incorrect value for last_msg_.certificate_bytes[192], expected 184, " - "is " - << last_msg_.certificate_bytes[192]; - EXPECT_EQ(last_msg_.certificate_bytes[193], 222) - << "incorrect value for last_msg_.certificate_bytes[193], expected 222, " - "is " - << last_msg_.certificate_bytes[193]; - EXPECT_EQ(last_msg_.certificate_bytes[194], 206) - << "incorrect value for last_msg_.certificate_bytes[194], expected 206, " - "is " - << last_msg_.certificate_bytes[194]; - EXPECT_EQ(last_msg_.certificate_bytes[195], 67) - << "incorrect value for last_msg_.certificate_bytes[195], expected 67, " - "is " - << last_msg_.certificate_bytes[195]; - EXPECT_EQ(last_msg_.certificate_bytes[196], 144) - << "incorrect value for last_msg_.certificate_bytes[196], expected 144, " - "is " - << last_msg_.certificate_bytes[196]; - EXPECT_EQ(last_msg_.certificate_bytes[197], 78) - << "incorrect value for last_msg_.certificate_bytes[197], expected 78, " - "is " - << last_msg_.certificate_bytes[197]; - EXPECT_EQ(last_msg_.certificate_bytes[198], 187) - << "incorrect value for last_msg_.certificate_bytes[198], expected 187, " - "is " - << last_msg_.certificate_bytes[198]; - EXPECT_EQ(last_msg_.certificate_bytes[199], 207) - << "incorrect value for last_msg_.certificate_bytes[199], expected 207, " - "is " - << last_msg_.certificate_bytes[199]; - EXPECT_EQ(last_msg_.certificate_bytes[200], 60) - << "incorrect value for last_msg_.certificate_bytes[200], expected 60, " - "is " - << last_msg_.certificate_bytes[200]; - EXPECT_EQ(last_msg_.certificate_bytes[201], 211) - << "incorrect value for last_msg_.certificate_bytes[201], expected 211, " - "is " - << last_msg_.certificate_bytes[201]; - EXPECT_EQ(last_msg_.certificate_bytes[202], 141) - << "incorrect value for last_msg_.certificate_bytes[202], expected 141, " - "is " - << last_msg_.certificate_bytes[202]; - EXPECT_EQ(last_msg_.certificate_bytes[203], 135) - << "incorrect value for last_msg_.certificate_bytes[203], expected 135, " - "is " - << last_msg_.certificate_bytes[203]; - EXPECT_EQ(last_msg_.certificate_bytes[204], 106) - << "incorrect value for last_msg_.certificate_bytes[204], expected 106, " - "is " - << last_msg_.certificate_bytes[204]; - EXPECT_EQ(last_msg_.certificate_bytes[205], 220) - << "incorrect value for last_msg_.certificate_bytes[205], expected 220, " - "is " - << last_msg_.certificate_bytes[205]; - EXPECT_EQ(last_msg_.certificate_bytes[206], 79) - << "incorrect value for last_msg_.certificate_bytes[206], expected 79, " - "is " - << last_msg_.certificate_bytes[206]; - EXPECT_EQ(last_msg_.certificate_bytes[207], 183) - << "incorrect value for last_msg_.certificate_bytes[207], expected 183, " - "is " - << last_msg_.certificate_bytes[207]; - EXPECT_EQ(last_msg_.certificate_bytes[208], 245) - << "incorrect value for last_msg_.certificate_bytes[208], expected 245, " - "is " - << last_msg_.certificate_bytes[208]; - EXPECT_EQ(last_msg_.certificate_bytes[209], 21) - << "incorrect value for last_msg_.certificate_bytes[209], expected 21, " - "is " - << last_msg_.certificate_bytes[209]; - EXPECT_EQ(last_msg_.certificate_bytes[210], 161) - << "incorrect value for last_msg_.certificate_bytes[210], expected 161, " - "is " - << last_msg_.certificate_bytes[210]; - EXPECT_EQ(last_msg_.certificate_bytes[211], 168) - << "incorrect value for last_msg_.certificate_bytes[211], expected 168, " - "is " - << last_msg_.certificate_bytes[211]; - EXPECT_EQ(last_msg_.certificate_bytes[212], 34) - << "incorrect value for last_msg_.certificate_bytes[212], expected 34, " - "is " - << last_msg_.certificate_bytes[212]; - EXPECT_EQ(last_msg_.certificate_bytes[213], 129) - << "incorrect value for last_msg_.certificate_bytes[213], expected 129, " - "is " - << last_msg_.certificate_bytes[213]; - EXPECT_EQ(last_msg_.certificate_bytes[214], 50) - << "incorrect value for last_msg_.certificate_bytes[214], expected 50, " - "is " - << last_msg_.certificate_bytes[214]; - EXPECT_EQ(last_msg_.certificate_bytes[215], 176) - << "incorrect value for last_msg_.certificate_bytes[215], expected 176, " - "is " - << last_msg_.certificate_bytes[215]; - EXPECT_EQ(last_msg_.certificate_bytes[216], 1) - << "incorrect value for last_msg_.certificate_bytes[216], expected 1, is " - << last_msg_.certificate_bytes[216]; - EXPECT_EQ(last_msg_.certificate_bytes[217], 218) - << "incorrect value for last_msg_.certificate_bytes[217], expected 218, " - "is " - << last_msg_.certificate_bytes[217]; - EXPECT_EQ(last_msg_.certificate_bytes[218], 20) - << "incorrect value for last_msg_.certificate_bytes[218], expected 20, " - "is " - << last_msg_.certificate_bytes[218]; - EXPECT_EQ(last_msg_.certificate_bytes[219], 130) - << "incorrect value for last_msg_.certificate_bytes[219], expected 130, " - "is " - << last_msg_.certificate_bytes[219]; - EXPECT_EQ(last_msg_.certificate_bytes[220], 59) - << "incorrect value for last_msg_.certificate_bytes[220], expected 59, " - "is " - << last_msg_.certificate_bytes[220]; - EXPECT_EQ(last_msg_.certificate_bytes[221], 249) - << "incorrect value for last_msg_.certificate_bytes[221], expected 249, " - "is " - << last_msg_.certificate_bytes[221]; - EXPECT_EQ(last_msg_.certificate_bytes[222], 109) - << "incorrect value for last_msg_.certificate_bytes[222], expected 109, " - "is " - << last_msg_.certificate_bytes[222]; - EXPECT_EQ(last_msg_.certificate_bytes[223], 219) - << "incorrect value for last_msg_.certificate_bytes[223], expected 219, " - "is " - << last_msg_.certificate_bytes[223]; - EXPECT_EQ(last_msg_.certificate_bytes[224], 0) - << "incorrect value for last_msg_.certificate_bytes[224], expected 0, is " - << last_msg_.certificate_bytes[224]; - EXPECT_EQ(last_msg_.certificate_bytes[225], 100) - << "incorrect value for last_msg_.certificate_bytes[225], expected 100, " - "is " - << last_msg_.certificate_bytes[225]; - EXPECT_EQ(last_msg_.certificate_bytes[226], 103) - << "incorrect value for last_msg_.certificate_bytes[226], expected 103, " - "is " - << last_msg_.certificate_bytes[226]; - EXPECT_EQ(last_msg_.certificate_bytes[227], 55) - << "incorrect value for last_msg_.certificate_bytes[227], expected 55, " - "is " - << last_msg_.certificate_bytes[227]; - EXPECT_EQ(last_msg_.certificate_bytes[228], 29) - << "incorrect value for last_msg_.certificate_bytes[228], expected 29, " - "is " - << last_msg_.certificate_bytes[228]; - EXPECT_EQ(last_msg_.certificate_bytes[229], 242) - << "incorrect value for last_msg_.certificate_bytes[229], expected 242, " - "is " - << last_msg_.certificate_bytes[229]; - EXPECT_EQ(last_msg_.certificate_bytes[230], 110) - << "incorrect value for last_msg_.certificate_bytes[230], expected 110, " - "is " - << last_msg_.certificate_bytes[230]; - EXPECT_EQ(last_msg_.certificate_bytes[231], 154) - << "incorrect value for last_msg_.certificate_bytes[231], expected 154, " - "is " - << last_msg_.certificate_bytes[231]; - EXPECT_EQ(last_msg_.certificate_bytes[232], 190) - << "incorrect value for last_msg_.certificate_bytes[232], expected 190, " - "is " - << last_msg_.certificate_bytes[232]; - EXPECT_EQ(last_msg_.certificate_bytes[233], 233) - << "incorrect value for last_msg_.certificate_bytes[233], expected 233, " - "is " - << last_msg_.certificate_bytes[233]; - EXPECT_EQ(last_msg_.certificate_bytes[234], 142) - << "incorrect value for last_msg_.certificate_bytes[234], expected 142, " - "is " - << last_msg_.certificate_bytes[234]; - EXPECT_EQ(last_msg_.certificate_bytes[235], 45) - << "incorrect value for last_msg_.certificate_bytes[235], expected 45, " - "is " - << last_msg_.certificate_bytes[235]; - EXPECT_EQ(last_msg_.certificate_bytes[236], 61) - << "incorrect value for last_msg_.certificate_bytes[236], expected 61, " - "is " - << last_msg_.certificate_bytes[236]; - EXPECT_EQ(last_msg_.certificate_bytes[237], 215) - << "incorrect value for last_msg_.certificate_bytes[237], expected 215, " - "is " - << last_msg_.certificate_bytes[237]; - EXPECT_EQ(last_msg_.certificate_bytes[238], 202) - << "incorrect value for last_msg_.certificate_bytes[238], expected 202, " - "is " - << last_msg_.certificate_bytes[238]; - EXPECT_EQ(last_msg_.certificate_bytes[239], 238) - << "incorrect value for last_msg_.certificate_bytes[239], expected 238, " - "is " - << last_msg_.certificate_bytes[239]; - EXPECT_EQ(last_msg_.certificate_bytes[240], 88) - << "incorrect value for last_msg_.certificate_bytes[240], expected 88, " - "is " - << last_msg_.certificate_bytes[240]; - EXPECT_EQ(last_msg_.certificate_bytes[241], 209) - << "incorrect value for last_msg_.certificate_bytes[241], expected 209, " - "is " - << last_msg_.certificate_bytes[241]; - EXPECT_EQ(last_msg_.certificate_bytes[242], 70) - << "incorrect value for last_msg_.certificate_bytes[242], expected 70, " - "is " - << last_msg_.certificate_bytes[242]; - EXPECT_EQ(last_msg_.certificate_bytes[243], 63) - << "incorrect value for last_msg_.certificate_bytes[243], expected 63, " - "is " - << last_msg_.certificate_bytes[243]; - EXPECT_EQ(last_msg_.certificate_bytes[244], 151) - << "incorrect value for last_msg_.certificate_bytes[244], expected 151, " - "is " - << last_msg_.certificate_bytes[244]; - EXPECT_EQ(last_msg_.certificate_bytes[245], 27) - << "incorrect value for last_msg_.certificate_bytes[245], expected 27, " - "is " - << last_msg_.certificate_bytes[245]; - EXPECT_EQ(last_msg_.certificate_bytes[246], 102) - << "incorrect value for last_msg_.certificate_bytes[246], expected 102, " - "is " - << last_msg_.certificate_bytes[246]; - EXPECT_EQ(last_msg_.certificate_id[0], 10) - << "incorrect value for last_msg_.certificate_id[0], expected 10, is " - << last_msg_.certificate_id[0]; - EXPECT_EQ(last_msg_.certificate_id[1], 11) - << "incorrect value for last_msg_.certificate_id[1], expected 11, is " - << last_msg_.certificate_id[1]; - EXPECT_EQ(last_msg_.certificate_id[2], 12) - << "incorrect value for last_msg_.certificate_id[2], expected 12, is " - << last_msg_.certificate_id[2]; - EXPECT_EQ(last_msg_.certificate_id[3], 13) - << "incorrect value for last_msg_.certificate_id[3], expected 13, is " - << last_msg_.certificate_id[3]; - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_certificate_bytes, 247) - << "incorrect value for last_msg_.n_certificate_bytes, expected 247, is " - << last_msg_.n_certificate_bytes; - EXPECT_EQ(last_msg_.n_msg, 48) - << "incorrect value for last_msg_.n_msg, expected 48, is " - << last_msg_.n_msg; + EXPECT_EQ(sbp_message_send(&state, SbpMsgEcdsaCertificate, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[0], + greater.certificate_bytes[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[1], + greater.certificate_bytes[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[2], + greater.certificate_bytes[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[3], + greater.certificate_bytes[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[4], + greater.certificate_bytes[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[5], + greater.certificate_bytes[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[6], + greater.certificate_bytes[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[7], + greater.certificate_bytes[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[8], + greater.certificate_bytes[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[9], + greater.certificate_bytes[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[10], + greater.certificate_bytes[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[11], + greater.certificate_bytes[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[12], + greater.certificate_bytes[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[13], + greater.certificate_bytes[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[14], + greater.certificate_bytes[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[15], + greater.certificate_bytes[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[16], + greater.certificate_bytes[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[17], + greater.certificate_bytes[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[18], + greater.certificate_bytes[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[19], + greater.certificate_bytes[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[20], + greater.certificate_bytes[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[21], + greater.certificate_bytes[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[22], + greater.certificate_bytes[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[23], + greater.certificate_bytes[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[24], + greater.certificate_bytes[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[25], + greater.certificate_bytes[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[26], + greater.certificate_bytes[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[27], + greater.certificate_bytes[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[28], + greater.certificate_bytes[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[29], + greater.certificate_bytes[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[30], + greater.certificate_bytes[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[31], + greater.certificate_bytes[31]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[32], + greater.certificate_bytes[32]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[33], + greater.certificate_bytes[33]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[34], + greater.certificate_bytes[34]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[35], + greater.certificate_bytes[35]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[36], + greater.certificate_bytes[36]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[37], + greater.certificate_bytes[37]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[38], + greater.certificate_bytes[38]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[39], + greater.certificate_bytes[39]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[40], + greater.certificate_bytes[40]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[41], + greater.certificate_bytes[41]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[42], + greater.certificate_bytes[42]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[43], + greater.certificate_bytes[43]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[44], + greater.certificate_bytes[44]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[45], + greater.certificate_bytes[45]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[46], + greater.certificate_bytes[46]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[47], + greater.certificate_bytes[47]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[48], + greater.certificate_bytes[48]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[49], + greater.certificate_bytes[49]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[50], + greater.certificate_bytes[50]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[51], + greater.certificate_bytes[51]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[52], + greater.certificate_bytes[52]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[53], + greater.certificate_bytes[53]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[54], + greater.certificate_bytes[54]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[55], + greater.certificate_bytes[55]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[56], + greater.certificate_bytes[56]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[57], + greater.certificate_bytes[57]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[58], + greater.certificate_bytes[58]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[59], + greater.certificate_bytes[59]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[60], + greater.certificate_bytes[60]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[61], + greater.certificate_bytes[61]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[62], + greater.certificate_bytes[62]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[63], + greater.certificate_bytes[63]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[64], + greater.certificate_bytes[64]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[65], + greater.certificate_bytes[65]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[66], + greater.certificate_bytes[66]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[67], + greater.certificate_bytes[67]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[68], + greater.certificate_bytes[68]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[69], + greater.certificate_bytes[69]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[70], + greater.certificate_bytes[70]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[71], + greater.certificate_bytes[71]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[72], + greater.certificate_bytes[72]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[73], + greater.certificate_bytes[73]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[74], + greater.certificate_bytes[74]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[75], + greater.certificate_bytes[75]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[76], + greater.certificate_bytes[76]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[77], + greater.certificate_bytes[77]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[78], + greater.certificate_bytes[78]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[79], + greater.certificate_bytes[79]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[80], + greater.certificate_bytes[80]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[81], + greater.certificate_bytes[81]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[82], + greater.certificate_bytes[82]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[83], + greater.certificate_bytes[83]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[84], + greater.certificate_bytes[84]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[85], + greater.certificate_bytes[85]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[86], + greater.certificate_bytes[86]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[87], + greater.certificate_bytes[87]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[88], + greater.certificate_bytes[88]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[89], + greater.certificate_bytes[89]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[90], + greater.certificate_bytes[90]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[91], + greater.certificate_bytes[91]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[92], + greater.certificate_bytes[92]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[93], + greater.certificate_bytes[93]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[94], + greater.certificate_bytes[94]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[95], + greater.certificate_bytes[95]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[96], + greater.certificate_bytes[96]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[97], + greater.certificate_bytes[97]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[98], + greater.certificate_bytes[98]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[99], + greater.certificate_bytes[99]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[100], + greater.certificate_bytes[100]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[101], + greater.certificate_bytes[101]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[102], + greater.certificate_bytes[102]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[103], + greater.certificate_bytes[103]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[104], + greater.certificate_bytes[104]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[105], + greater.certificate_bytes[105]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[106], + greater.certificate_bytes[106]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[107], + greater.certificate_bytes[107]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[108], + greater.certificate_bytes[108]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[109], + greater.certificate_bytes[109]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[110], + greater.certificate_bytes[110]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[111], + greater.certificate_bytes[111]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[112], + greater.certificate_bytes[112]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[113], + greater.certificate_bytes[113]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[114], + greater.certificate_bytes[114]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[115], + greater.certificate_bytes[115]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[116], + greater.certificate_bytes[116]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[117], + greater.certificate_bytes[117]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[118], + greater.certificate_bytes[118]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[119], + greater.certificate_bytes[119]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[120], + greater.certificate_bytes[120]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[121], + greater.certificate_bytes[121]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[122], + greater.certificate_bytes[122]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[123], + greater.certificate_bytes[123]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[124], + greater.certificate_bytes[124]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[125], + greater.certificate_bytes[125]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[126], + greater.certificate_bytes[126]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[127], + greater.certificate_bytes[127]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[128], + greater.certificate_bytes[128]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[129], + greater.certificate_bytes[129]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[130], + greater.certificate_bytes[130]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[131], + greater.certificate_bytes[131]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[132], + greater.certificate_bytes[132]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[133], + greater.certificate_bytes[133]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[134], + greater.certificate_bytes[134]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[135], + greater.certificate_bytes[135]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[136], + greater.certificate_bytes[136]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[137], + greater.certificate_bytes[137]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[138], + greater.certificate_bytes[138]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[139], + greater.certificate_bytes[139]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[140], + greater.certificate_bytes[140]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[141], + greater.certificate_bytes[141]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[142], + greater.certificate_bytes[142]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[143], + greater.certificate_bytes[143]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[144], + greater.certificate_bytes[144]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[145], + greater.certificate_bytes[145]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[146], + greater.certificate_bytes[146]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[147], + greater.certificate_bytes[147]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[148], + greater.certificate_bytes[148]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[149], + greater.certificate_bytes[149]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[150], + greater.certificate_bytes[150]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[151], + greater.certificate_bytes[151]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[152], + greater.certificate_bytes[152]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[153], + greater.certificate_bytes[153]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[154], + greater.certificate_bytes[154]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[155], + greater.certificate_bytes[155]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[156], + greater.certificate_bytes[156]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[157], + greater.certificate_bytes[157]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[158], + greater.certificate_bytes[158]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[159], + greater.certificate_bytes[159]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[160], + greater.certificate_bytes[160]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[161], + greater.certificate_bytes[161]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[162], + greater.certificate_bytes[162]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[163], + greater.certificate_bytes[163]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[164], + greater.certificate_bytes[164]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[165], + greater.certificate_bytes[165]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[166], + greater.certificate_bytes[166]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[167], + greater.certificate_bytes[167]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[168], + greater.certificate_bytes[168]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[169], + greater.certificate_bytes[169]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[170], + greater.certificate_bytes[170]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[171], + greater.certificate_bytes[171]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[172], + greater.certificate_bytes[172]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[173], + greater.certificate_bytes[173]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[174], + greater.certificate_bytes[174]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[175], + greater.certificate_bytes[175]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[176], + greater.certificate_bytes[176]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[177], + greater.certificate_bytes[177]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[178], + greater.certificate_bytes[178]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[179], + greater.certificate_bytes[179]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[180], + greater.certificate_bytes[180]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[181], + greater.certificate_bytes[181]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[182], + greater.certificate_bytes[182]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[183], + greater.certificate_bytes[183]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[184], + greater.certificate_bytes[184]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[185], + greater.certificate_bytes[185]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[186], + greater.certificate_bytes[186]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[187], + greater.certificate_bytes[187]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[188], + greater.certificate_bytes[188]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[189], + greater.certificate_bytes[189]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[190], + greater.certificate_bytes[190]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[191], + greater.certificate_bytes[191]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[192], + greater.certificate_bytes[192]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[193], + greater.certificate_bytes[193]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[194], + greater.certificate_bytes[194]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[195], + greater.certificate_bytes[195]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[196], + greater.certificate_bytes[196]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[197], + greater.certificate_bytes[197]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[198], + greater.certificate_bytes[198]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[199], + greater.certificate_bytes[199]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[200], + greater.certificate_bytes[200]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[201], + greater.certificate_bytes[201]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[202], + greater.certificate_bytes[202]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[203], + greater.certificate_bytes[203]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[204], + greater.certificate_bytes[204]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[205], + greater.certificate_bytes[205]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[206], + greater.certificate_bytes[206]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[207], + greater.certificate_bytes[207]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[208], + greater.certificate_bytes[208]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[209], + greater.certificate_bytes[209]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[210], + greater.certificate_bytes[210]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[211], + greater.certificate_bytes[211]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[212], + greater.certificate_bytes[212]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[213], + greater.certificate_bytes[213]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[214], + greater.certificate_bytes[214]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[215], + greater.certificate_bytes[215]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[216], + greater.certificate_bytes[216]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[217], + greater.certificate_bytes[217]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[218], + greater.certificate_bytes[218]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[219], + greater.certificate_bytes[219]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[220], + greater.certificate_bytes[220]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[221], + greater.certificate_bytes[221]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[222], + greater.certificate_bytes[222]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[223], + greater.certificate_bytes[223]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[224], + greater.certificate_bytes[224]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[225], + greater.certificate_bytes[225]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[226], + greater.certificate_bytes[226]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[227], + greater.certificate_bytes[227]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[228], + greater.certificate_bytes[228]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[229], + greater.certificate_bytes[229]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[230], + greater.certificate_bytes[230]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[231], + greater.certificate_bytes[231]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[232], + greater.certificate_bytes[232]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[233], + greater.certificate_bytes[233]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[234], + greater.certificate_bytes[234]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[235], + greater.certificate_bytes[235]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[236], + greater.certificate_bytes[236]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[237], + greater.certificate_bytes[237]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[238], + greater.certificate_bytes[238]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[239], + greater.certificate_bytes[239]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[240], + greater.certificate_bytes[240]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[241], + greater.certificate_bytes[241]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[242], + greater.certificate_bytes[242]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[243], + greater.certificate_bytes[243]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[244], + greater.certificate_bytes[244]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[245], + greater.certificate_bytes[245]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[246], + greater.certificate_bytes[246]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[0], greater.certificate_id[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[1], greater.certificate_id[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[2], greater.certificate_id[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[3], greater.certificate_id[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.n_certificate_bytes, + greater.n_certificate_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_certificate_t lesser = info.test_msg; + sbp_msg_ecdsa_certificate_t greater = info.test_msg; + make_lesser_greater(lesser.n_msg, greater.n_msg); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEcdsaCertificate); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ECDSA_CERTIFICATE"); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ecdsa_certificate_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ecdsa_certificate_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ecdsa_certificate, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ecdsa_certificate, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[253]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 253); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 253), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_certificate_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 253); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEcdsaCertificate, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaCertificate0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEcdsaCertificate, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignature.cc b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignature.cc index c0993550bf..69c3d4fccf 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignature.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignature.cc @@ -16,66 +16,438 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEcdsaSignature0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEcdsaSignature0 : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEcdsaSignature0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgEcdsaSignature0() { + assign(test_msg_.certificate_id[0], 1); + + assign(test_msg_.certificate_id[1], 2); + + assign(test_msg_.certificate_id[2], 3); + + assign(test_msg_.certificate_id[3], 4); + assign(test_msg_.flags, 0); + assign(test_msg_.n_signed_messages, 3); + assign(test_msg_.on_demand_counter, 2); + + assign(test_msg_.signature.data[0], 0); + + assign(test_msg_.signature.data[1], 1); + + assign(test_msg_.signature.data[2], 2); + + assign(test_msg_.signature.data[3], 3); + + assign(test_msg_.signature.data[4], 4); + + assign(test_msg_.signature.data[5], 5); + + assign(test_msg_.signature.data[6], 6); + + assign(test_msg_.signature.data[7], 7); + + assign(test_msg_.signature.data[8], 8); + + assign(test_msg_.signature.data[9], 9); + + assign(test_msg_.signature.data[10], 10); + + assign(test_msg_.signature.data[11], 11); + + assign(test_msg_.signature.data[12], 12); + + assign(test_msg_.signature.data[13], 13); + + assign(test_msg_.signature.data[14], 14); + + assign(test_msg_.signature.data[15], 15); + + assign(test_msg_.signature.data[16], 16); + + assign(test_msg_.signature.data[17], 17); + + assign(test_msg_.signature.data[18], 18); + + assign(test_msg_.signature.data[19], 19); + + assign(test_msg_.signature.data[20], 20); + + assign(test_msg_.signature.data[21], 21); + + assign(test_msg_.signature.data[22], 22); + + assign(test_msg_.signature.data[23], 23); + + assign(test_msg_.signature.data[24], 24); + + assign(test_msg_.signature.data[25], 25); + + assign(test_msg_.signature.data[26], 26); + + assign(test_msg_.signature.data[27], 27); + + assign(test_msg_.signature.data[28], 28); + + assign(test_msg_.signature.data[29], 29); + + assign(test_msg_.signature.data[30], 30); + + assign(test_msg_.signature.data[31], 31); + + assign(test_msg_.signature.data[32], 32); + + assign(test_msg_.signature.data[33], 33); + + assign(test_msg_.signature.data[34], 34); + + assign(test_msg_.signature.data[35], 35); + + assign(test_msg_.signature.data[36], 36); + + assign(test_msg_.signature.data[37], 37); + + assign(test_msg_.signature.data[38], 38); + + assign(test_msg_.signature.data[39], 39); + + assign(test_msg_.signature.data[40], 40); + + assign(test_msg_.signature.data[41], 41); + + assign(test_msg_.signature.data[42], 42); + + assign(test_msg_.signature.data[43], 43); + + assign(test_msg_.signature.data[44], 44); + + assign(test_msg_.signature.data[45], 45); + + assign(test_msg_.signature.data[46], 46); + + assign(test_msg_.signature.data[47], 47); + + assign(test_msg_.signature.data[48], 48); + + assign(test_msg_.signature.data[49], 49); + + assign(test_msg_.signature.data[50], 50); + + assign(test_msg_.signature.data[51], 51); + + assign(test_msg_.signature.data[52], 52); + + assign(test_msg_.signature.data[53], 53); + + assign(test_msg_.signature.data[54], 54); + + assign(test_msg_.signature.data[55], 55); + + assign(test_msg_.signature.data[56], 56); + + assign(test_msg_.signature.data[57], 57); + + assign(test_msg_.signature.data[58], 58); + + assign(test_msg_.signature.data[59], 59); + + assign(test_msg_.signature.data[60], 60); + + assign(test_msg_.signature.data[61], 61); + + assign(test_msg_.signature.data[62], 62); + + assign(test_msg_.signature.data[63], 63); + + assign(test_msg_.signature.data[64], 64); + + assign(test_msg_.signature.data[65], 65); + + assign(test_msg_.signature.data[66], 66); + + assign(test_msg_.signature.data[67], 67); + + assign(test_msg_.signature.data[68], 68); + + assign(test_msg_.signature.data[69], 69); + + assign(test_msg_.signature.data[70], 70); + + assign(test_msg_.signature.data[71], 71); + assign(test_msg_.signature.len, 72); + + assign(test_msg_.signed_messages[0], 10); + + assign(test_msg_.signed_messages[1], 21); + + assign(test_msg_.signed_messages[2], 23); + assign(test_msg_.stream_counter, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ecdsa_signature_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEcdsaSignature, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEcdsaSignature); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ecdsa_signature, + sizeof(msg->ecdsa_signature)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ecdsa_signature_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ecdsa_signature, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEcdsaSignature); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x83E8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 83; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ecdsa_signature_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ecdsa_signature_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ecdsa_signature_t &lesser, + const sbp_msg_ecdsa_signature_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ecdsa_signature_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ecdsa_signature_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ecdsa_signature_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ecdsa_signature_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgEcdsaSignature, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaSignature, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEcdsaSignature, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEcdsaSignature, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_signing_MsgEcdsaSignature0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ecdsa_signature_t test_msg_{}; + uint8_t encoded_frame_[83 + 8] = { 85, 8, 12, 66, 0, 83, 0, 1, 2, 1, 2, 3, 4, 72, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -83,434 +455,899 @@ TEST_F(Test_auto_check_sbp_signing_MsgEcdsaSignature0, Test) { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 10, 21, 23, 232, 131, }; + uint8_t encoded_payload_[83] = { + 0, 1, 2, 1, 2, 3, 4, 72, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 10, 21, 23, + }; +}; - sbp_msg_ecdsa_signature_t test_msg{}; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ecdsa_signature_encoded_len(&info.test_msg), + info.payload_len); - test_msg.certificate_id[0] = 1; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEcdsaSignature, &info.test_msg_wrapped), + info.payload_len); +} - test_msg.certificate_id[1] = 2; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ecdsa_signature_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEcdsaSignature, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} - test_msg.certificate_id[2] = 3; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[83]; - test_msg.certificate_id[3] = 4; - test_msg.flags = 0; - test_msg.n_signed_messages = 3; - test_msg.on_demand_counter = 2; + EXPECT_EQ(sbp_msg_ecdsa_signature_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + + for (uint8_t i = 0; i < 83; i++) { + EXPECT_EQ( + sbp_msg_ecdsa_signature_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.signature.data[0] = 0; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ecdsa_signature_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEcdsaSignature, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signature.data[1] = 1; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_t msg{}; - test_msg.signature.data[2] = 2; + EXPECT_EQ(sbp_msg_ecdsa_signature_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ecdsa_signature_t t{}; + return sbp_msg_ecdsa_signature_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ecdsa_signature_t t{}; + t.n_signed_messages = 1; + return sbp_msg_ecdsa_signature_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ecdsa_signature_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} - test_msg.signature.data[3] = 3; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature.data[4] = 4; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.signature.data[5] = 5; + CHandler handler{&state}; - test_msg.signature.data[6] = 6; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.signature.data[7] = 7; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.signature.data[8] = 8; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature.data[9] = 9; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature.data[10] = 10; + EXPECT_EQ(sbp_msg_ecdsa_signature_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.signature.data[11] = 11; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature.data[12] = 12; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature.data[13] = 13; + EXPECT_EQ(sbp_message_send(&state, SbpMsgEcdsaSignature, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.signature.data[14] = 14; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, Comparison) { + auto info = get_test_msg_info(); - test_msg.signature.data[15] = 15; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[0], greater.certificate_id[0]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[16] = 16; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[1], greater.certificate_id[1]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[17] = 17; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[2], greater.certificate_id[2]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[18] = 18; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[3], greater.certificate_id[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.n_signed_messages, greater.n_signed_messages); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.on_demand_counter, greater.on_demand_counter); + comparison_tests(lesser, greater); + } - test_msg.signature.data[19] = 19; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[0], greater.signature.data[0]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[20] = 20; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[1], greater.signature.data[1]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[21] = 21; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[2], greater.signature.data[2]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[22] = 22; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[3], greater.signature.data[3]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[23] = 23; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[4], greater.signature.data[4]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[24] = 24; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[5], greater.signature.data[5]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[25] = 25; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[6], greater.signature.data[6]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[26] = 26; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[7], greater.signature.data[7]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[27] = 27; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[8], greater.signature.data[8]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[28] = 28; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[9], greater.signature.data[9]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[29] = 29; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[10], greater.signature.data[10]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[30] = 30; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[11], greater.signature.data[11]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[31] = 31; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[12], greater.signature.data[12]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[32] = 32; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[13], greater.signature.data[13]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[33] = 33; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[14], greater.signature.data[14]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[34] = 34; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[15], greater.signature.data[15]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[35] = 35; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[16], greater.signature.data[16]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[36] = 36; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[17], greater.signature.data[17]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[37] = 37; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[18], greater.signature.data[18]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[38] = 38; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[19], greater.signature.data[19]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[39] = 39; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[20], greater.signature.data[20]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[40] = 40; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[21], greater.signature.data[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[22], greater.signature.data[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[23], greater.signature.data[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[24], greater.signature.data[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[25], greater.signature.data[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[26], greater.signature.data[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[27], greater.signature.data[27]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[41] = 41; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[28], greater.signature.data[28]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[42] = 42; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[29], greater.signature.data[29]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[43] = 43; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[30], greater.signature.data[30]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[44] = 44; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[31], greater.signature.data[31]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[45] = 45; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[32], greater.signature.data[32]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[46] = 46; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[33], greater.signature.data[33]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[47] = 47; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[34], greater.signature.data[34]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[48] = 48; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[35], greater.signature.data[35]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[49] = 49; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[36], greater.signature.data[36]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[50] = 50; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[37], greater.signature.data[37]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[51] = 51; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[38], greater.signature.data[38]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[52] = 52; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[39], greater.signature.data[39]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[53] = 53; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[40], greater.signature.data[40]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[54] = 54; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[41], greater.signature.data[41]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[55] = 55; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[42], greater.signature.data[42]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[56] = 56; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[43], greater.signature.data[43]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[57] = 57; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[44], greater.signature.data[44]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[58] = 58; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[45], greater.signature.data[45]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[59] = 59; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[46], greater.signature.data[46]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[60] = 60; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[47], greater.signature.data[47]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[61] = 61; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[48], greater.signature.data[48]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[62] = 62; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[49], greater.signature.data[49]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[63] = 63; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[50], greater.signature.data[50]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[64] = 64; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[51], greater.signature.data[51]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[65] = 65; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[52], greater.signature.data[52]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[66] = 66; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[53], greater.signature.data[53]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[67] = 67; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[54], greater.signature.data[54]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[68] = 68; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[55], greater.signature.data[55]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[69] = 69; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[56], greater.signature.data[56]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[70] = 70; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[57], greater.signature.data[57]); + comparison_tests(lesser, greater); + } - test_msg.signature.data[71] = 71; - test_msg.signature.len = 72; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[58], greater.signature.data[58]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[0] = 10; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[59], greater.signature.data[59]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[1] = 21; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[60], greater.signature.data[60]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[2] = 23; - test_msg.stream_counter = 1; + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[61], greater.signature.data[61]); + comparison_tests(lesser, greater); + } - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[62], greater.signature.data[62]); + comparison_tests(lesser, greater); + } - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[63], greater.signature.data[63]); + comparison_tests(lesser, greater); + } - while (dummy_rd_ < dummy_wr_) { - process(); + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[64], greater.signature.data[64]); + comparison_tests(lesser, greater); } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.certificate_id[0], 1) - << "incorrect value for last_msg_.certificate_id[0], expected 1, is " - << last_msg_.certificate_id[0]; - EXPECT_EQ(last_msg_.certificate_id[1], 2) - << "incorrect value for last_msg_.certificate_id[1], expected 2, is " - << last_msg_.certificate_id[1]; - EXPECT_EQ(last_msg_.certificate_id[2], 3) - << "incorrect value for last_msg_.certificate_id[2], expected 3, is " - << last_msg_.certificate_id[2]; - EXPECT_EQ(last_msg_.certificate_id[3], 4) - << "incorrect value for last_msg_.certificate_id[3], expected 4, is " - << last_msg_.certificate_id[3]; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_signed_messages, 3) - << "incorrect value for last_msg_.n_signed_messages, expected 3, is " - << last_msg_.n_signed_messages; - EXPECT_EQ(last_msg_.on_demand_counter, 2) - << "incorrect value for last_msg_.on_demand_counter, expected 2, is " - << last_msg_.on_demand_counter; - EXPECT_EQ(last_msg_.signature.data[0], 0) - << "incorrect value for last_msg_.signature.data[0], expected 0, is " - << last_msg_.signature.data[0]; - EXPECT_EQ(last_msg_.signature.data[1], 1) - << "incorrect value for last_msg_.signature.data[1], expected 1, is " - << last_msg_.signature.data[1]; - EXPECT_EQ(last_msg_.signature.data[2], 2) - << "incorrect value for last_msg_.signature.data[2], expected 2, is " - << last_msg_.signature.data[2]; - EXPECT_EQ(last_msg_.signature.data[3], 3) - << "incorrect value for last_msg_.signature.data[3], expected 3, is " - << last_msg_.signature.data[3]; - EXPECT_EQ(last_msg_.signature.data[4], 4) - << "incorrect value for last_msg_.signature.data[4], expected 4, is " - << last_msg_.signature.data[4]; - EXPECT_EQ(last_msg_.signature.data[5], 5) - << "incorrect value for last_msg_.signature.data[5], expected 5, is " - << last_msg_.signature.data[5]; - EXPECT_EQ(last_msg_.signature.data[6], 6) - << "incorrect value for last_msg_.signature.data[6], expected 6, is " - << last_msg_.signature.data[6]; - EXPECT_EQ(last_msg_.signature.data[7], 7) - << "incorrect value for last_msg_.signature.data[7], expected 7, is " - << last_msg_.signature.data[7]; - EXPECT_EQ(last_msg_.signature.data[8], 8) - << "incorrect value for last_msg_.signature.data[8], expected 8, is " - << last_msg_.signature.data[8]; - EXPECT_EQ(last_msg_.signature.data[9], 9) - << "incorrect value for last_msg_.signature.data[9], expected 9, is " - << last_msg_.signature.data[9]; - EXPECT_EQ(last_msg_.signature.data[10], 10) - << "incorrect value for last_msg_.signature.data[10], expected 10, is " - << last_msg_.signature.data[10]; - EXPECT_EQ(last_msg_.signature.data[11], 11) - << "incorrect value for last_msg_.signature.data[11], expected 11, is " - << last_msg_.signature.data[11]; - EXPECT_EQ(last_msg_.signature.data[12], 12) - << "incorrect value for last_msg_.signature.data[12], expected 12, is " - << last_msg_.signature.data[12]; - EXPECT_EQ(last_msg_.signature.data[13], 13) - << "incorrect value for last_msg_.signature.data[13], expected 13, is " - << last_msg_.signature.data[13]; - EXPECT_EQ(last_msg_.signature.data[14], 14) - << "incorrect value for last_msg_.signature.data[14], expected 14, is " - << last_msg_.signature.data[14]; - EXPECT_EQ(last_msg_.signature.data[15], 15) - << "incorrect value for last_msg_.signature.data[15], expected 15, is " - << last_msg_.signature.data[15]; - EXPECT_EQ(last_msg_.signature.data[16], 16) - << "incorrect value for last_msg_.signature.data[16], expected 16, is " - << last_msg_.signature.data[16]; - EXPECT_EQ(last_msg_.signature.data[17], 17) - << "incorrect value for last_msg_.signature.data[17], expected 17, is " - << last_msg_.signature.data[17]; - EXPECT_EQ(last_msg_.signature.data[18], 18) - << "incorrect value for last_msg_.signature.data[18], expected 18, is " - << last_msg_.signature.data[18]; - EXPECT_EQ(last_msg_.signature.data[19], 19) - << "incorrect value for last_msg_.signature.data[19], expected 19, is " - << last_msg_.signature.data[19]; - EXPECT_EQ(last_msg_.signature.data[20], 20) - << "incorrect value for last_msg_.signature.data[20], expected 20, is " - << last_msg_.signature.data[20]; - EXPECT_EQ(last_msg_.signature.data[21], 21) - << "incorrect value for last_msg_.signature.data[21], expected 21, is " - << last_msg_.signature.data[21]; - EXPECT_EQ(last_msg_.signature.data[22], 22) - << "incorrect value for last_msg_.signature.data[22], expected 22, is " - << last_msg_.signature.data[22]; - EXPECT_EQ(last_msg_.signature.data[23], 23) - << "incorrect value for last_msg_.signature.data[23], expected 23, is " - << last_msg_.signature.data[23]; - EXPECT_EQ(last_msg_.signature.data[24], 24) - << "incorrect value for last_msg_.signature.data[24], expected 24, is " - << last_msg_.signature.data[24]; - EXPECT_EQ(last_msg_.signature.data[25], 25) - << "incorrect value for last_msg_.signature.data[25], expected 25, is " - << last_msg_.signature.data[25]; - EXPECT_EQ(last_msg_.signature.data[26], 26) - << "incorrect value for last_msg_.signature.data[26], expected 26, is " - << last_msg_.signature.data[26]; - EXPECT_EQ(last_msg_.signature.data[27], 27) - << "incorrect value for last_msg_.signature.data[27], expected 27, is " - << last_msg_.signature.data[27]; - EXPECT_EQ(last_msg_.signature.data[28], 28) - << "incorrect value for last_msg_.signature.data[28], expected 28, is " - << last_msg_.signature.data[28]; - EXPECT_EQ(last_msg_.signature.data[29], 29) - << "incorrect value for last_msg_.signature.data[29], expected 29, is " - << last_msg_.signature.data[29]; - EXPECT_EQ(last_msg_.signature.data[30], 30) - << "incorrect value for last_msg_.signature.data[30], expected 30, is " - << last_msg_.signature.data[30]; - EXPECT_EQ(last_msg_.signature.data[31], 31) - << "incorrect value for last_msg_.signature.data[31], expected 31, is " - << last_msg_.signature.data[31]; - EXPECT_EQ(last_msg_.signature.data[32], 32) - << "incorrect value for last_msg_.signature.data[32], expected 32, is " - << last_msg_.signature.data[32]; - EXPECT_EQ(last_msg_.signature.data[33], 33) - << "incorrect value for last_msg_.signature.data[33], expected 33, is " - << last_msg_.signature.data[33]; - EXPECT_EQ(last_msg_.signature.data[34], 34) - << "incorrect value for last_msg_.signature.data[34], expected 34, is " - << last_msg_.signature.data[34]; - EXPECT_EQ(last_msg_.signature.data[35], 35) - << "incorrect value for last_msg_.signature.data[35], expected 35, is " - << last_msg_.signature.data[35]; - EXPECT_EQ(last_msg_.signature.data[36], 36) - << "incorrect value for last_msg_.signature.data[36], expected 36, is " - << last_msg_.signature.data[36]; - EXPECT_EQ(last_msg_.signature.data[37], 37) - << "incorrect value for last_msg_.signature.data[37], expected 37, is " - << last_msg_.signature.data[37]; - EXPECT_EQ(last_msg_.signature.data[38], 38) - << "incorrect value for last_msg_.signature.data[38], expected 38, is " - << last_msg_.signature.data[38]; - EXPECT_EQ(last_msg_.signature.data[39], 39) - << "incorrect value for last_msg_.signature.data[39], expected 39, is " - << last_msg_.signature.data[39]; - EXPECT_EQ(last_msg_.signature.data[40], 40) - << "incorrect value for last_msg_.signature.data[40], expected 40, is " - << last_msg_.signature.data[40]; - EXPECT_EQ(last_msg_.signature.data[41], 41) - << "incorrect value for last_msg_.signature.data[41], expected 41, is " - << last_msg_.signature.data[41]; - EXPECT_EQ(last_msg_.signature.data[42], 42) - << "incorrect value for last_msg_.signature.data[42], expected 42, is " - << last_msg_.signature.data[42]; - EXPECT_EQ(last_msg_.signature.data[43], 43) - << "incorrect value for last_msg_.signature.data[43], expected 43, is " - << last_msg_.signature.data[43]; - EXPECT_EQ(last_msg_.signature.data[44], 44) - << "incorrect value for last_msg_.signature.data[44], expected 44, is " - << last_msg_.signature.data[44]; - EXPECT_EQ(last_msg_.signature.data[45], 45) - << "incorrect value for last_msg_.signature.data[45], expected 45, is " - << last_msg_.signature.data[45]; - EXPECT_EQ(last_msg_.signature.data[46], 46) - << "incorrect value for last_msg_.signature.data[46], expected 46, is " - << last_msg_.signature.data[46]; - EXPECT_EQ(last_msg_.signature.data[47], 47) - << "incorrect value for last_msg_.signature.data[47], expected 47, is " - << last_msg_.signature.data[47]; - EXPECT_EQ(last_msg_.signature.data[48], 48) - << "incorrect value for last_msg_.signature.data[48], expected 48, is " - << last_msg_.signature.data[48]; - EXPECT_EQ(last_msg_.signature.data[49], 49) - << "incorrect value for last_msg_.signature.data[49], expected 49, is " - << last_msg_.signature.data[49]; - EXPECT_EQ(last_msg_.signature.data[50], 50) - << "incorrect value for last_msg_.signature.data[50], expected 50, is " - << last_msg_.signature.data[50]; - EXPECT_EQ(last_msg_.signature.data[51], 51) - << "incorrect value for last_msg_.signature.data[51], expected 51, is " - << last_msg_.signature.data[51]; - EXPECT_EQ(last_msg_.signature.data[52], 52) - << "incorrect value for last_msg_.signature.data[52], expected 52, is " - << last_msg_.signature.data[52]; - EXPECT_EQ(last_msg_.signature.data[53], 53) - << "incorrect value for last_msg_.signature.data[53], expected 53, is " - << last_msg_.signature.data[53]; - EXPECT_EQ(last_msg_.signature.data[54], 54) - << "incorrect value for last_msg_.signature.data[54], expected 54, is " - << last_msg_.signature.data[54]; - EXPECT_EQ(last_msg_.signature.data[55], 55) - << "incorrect value for last_msg_.signature.data[55], expected 55, is " - << last_msg_.signature.data[55]; - EXPECT_EQ(last_msg_.signature.data[56], 56) - << "incorrect value for last_msg_.signature.data[56], expected 56, is " - << last_msg_.signature.data[56]; - EXPECT_EQ(last_msg_.signature.data[57], 57) - << "incorrect value for last_msg_.signature.data[57], expected 57, is " - << last_msg_.signature.data[57]; - EXPECT_EQ(last_msg_.signature.data[58], 58) - << "incorrect value for last_msg_.signature.data[58], expected 58, is " - << last_msg_.signature.data[58]; - EXPECT_EQ(last_msg_.signature.data[59], 59) - << "incorrect value for last_msg_.signature.data[59], expected 59, is " - << last_msg_.signature.data[59]; - EXPECT_EQ(last_msg_.signature.data[60], 60) - << "incorrect value for last_msg_.signature.data[60], expected 60, is " - << last_msg_.signature.data[60]; - EXPECT_EQ(last_msg_.signature.data[61], 61) - << "incorrect value for last_msg_.signature.data[61], expected 61, is " - << last_msg_.signature.data[61]; - EXPECT_EQ(last_msg_.signature.data[62], 62) - << "incorrect value for last_msg_.signature.data[62], expected 62, is " - << last_msg_.signature.data[62]; - EXPECT_EQ(last_msg_.signature.data[63], 63) - << "incorrect value for last_msg_.signature.data[63], expected 63, is " - << last_msg_.signature.data[63]; - EXPECT_EQ(last_msg_.signature.data[64], 64) - << "incorrect value for last_msg_.signature.data[64], expected 64, is " - << last_msg_.signature.data[64]; - EXPECT_EQ(last_msg_.signature.data[65], 65) - << "incorrect value for last_msg_.signature.data[65], expected 65, is " - << last_msg_.signature.data[65]; - EXPECT_EQ(last_msg_.signature.data[66], 66) - << "incorrect value for last_msg_.signature.data[66], expected 66, is " - << last_msg_.signature.data[66]; - EXPECT_EQ(last_msg_.signature.data[67], 67) - << "incorrect value for last_msg_.signature.data[67], expected 67, is " - << last_msg_.signature.data[67]; - EXPECT_EQ(last_msg_.signature.data[68], 68) - << "incorrect value for last_msg_.signature.data[68], expected 68, is " - << last_msg_.signature.data[68]; - EXPECT_EQ(last_msg_.signature.data[69], 69) - << "incorrect value for last_msg_.signature.data[69], expected 69, is " - << last_msg_.signature.data[69]; - EXPECT_EQ(last_msg_.signature.data[70], 70) - << "incorrect value for last_msg_.signature.data[70], expected 70, is " - << last_msg_.signature.data[70]; - EXPECT_EQ(last_msg_.signature.data[71], 71) - << "incorrect value for last_msg_.signature.data[71], expected 71, is " - << last_msg_.signature.data[71]; - EXPECT_EQ(last_msg_.signature.len, 72) - << "incorrect value for last_msg_.signature.len, expected 72, is " - << last_msg_.signature.len; - EXPECT_EQ(last_msg_.signed_messages[0], 10) - << "incorrect value for last_msg_.signed_messages[0], expected 10, is " - << last_msg_.signed_messages[0]; - EXPECT_EQ(last_msg_.signed_messages[1], 21) - << "incorrect value for last_msg_.signed_messages[1], expected 21, is " - << last_msg_.signed_messages[1]; - EXPECT_EQ(last_msg_.signed_messages[2], 23) - << "incorrect value for last_msg_.signed_messages[2], expected 23, is " - << last_msg_.signed_messages[2]; - EXPECT_EQ(last_msg_.stream_counter, 1) - << "incorrect value for last_msg_.stream_counter, expected 1, is " - << last_msg_.stream_counter; + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[65], greater.signature.data[65]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[66], greater.signature.data[66]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[67], greater.signature.data[67]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[68], greater.signature.data[68]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[69], greater.signature.data[69]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[70], greater.signature.data[70]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.data[71], greater.signature.data[71]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signature.len, greater.signature.len); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[0], greater.signed_messages[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[1], greater.signed_messages[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[2], greater.signed_messages[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_t greater = info.test_msg; + make_lesser_greater(lesser.stream_counter, greater.stream_counter); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEcdsaSignature); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ECDSA_SIGNATURE"); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ecdsa_signature_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ecdsa_signature_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ecdsa_signature, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ecdsa_signature, info.test_msg); } + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEcdsaSignature, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignature0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEcdsaSignature, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepA.cc b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepA.cc index 3695ed6590..ae385386a3 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepA.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepA.cc @@ -16,1374 +16,3097 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEcdsaSignatureDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEcdsaSignatureDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0() { + assign(test_msg_.certificate_id[0], 1); - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ecdsa_signature_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ecdsa_signature_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + assign(test_msg_.certificate_id[1], 2); -TEST_F(Test_auto_check_sbp_signing_MsgEcdsaSignatureDepA0, Test) { - uint8_t encoded_frame[] = { - 85, 6, 12, 66, 0, 255, 0, 1, 2, 1, 2, 3, 4, 0, 1, - 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, - 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, - 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, - 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, - 6, 7, 10, 21, 23, 63, 140, 37, 130, 106, 28, 40, 165, 179, 73, - 178, 60, 126, 114, 78, 113, 27, 95, 3, 62, 104, 145, 96, 19, 92, - 123, 14, 90, 153, 183, 9, 72, 81, 118, 112, 124, 16, 182, 76, 146, - 115, 58, 144, 17, 105, 66, 31, 135, 54, 100, 84, 181, 103, 11, 88, - 133, 155, 167, 173, 143, 86, 158, 20, 168, 132, 141, 102, 50, 48, 71, - 147, 53, 87, 1, 108, 138, 36, 134, 139, 163, 82, 43, 52, 150, 12, - 30, 110, 156, 107, 120, 91, 122, 69, 164, 170, 116, 25, 94, 5, 22, - 24, 162, 175, 38, 157, 98, 44, 160, 47, 97, 142, 8, 74, 13, 177, - 15, 128, 26, 131, 154, 65, 169, 55, 136, 125, 171, 161, 29, 129, 151, - 68, 166, 51, 70, 45, 56, 79, 149, 99, 42, 101, 152, 39, 89, 180, - 64, 49, 6, 80, 172, 32, 109, 2, 119, 93, 176, 0, 33, 57, 34, - 18, 85, 121, 137, 83, 111, 59, 7, 77, 4, 117, 159, 148, 35, 61, - 41, 67, 46, 127, 75, 174, 97, 172, - }; + assign(test_msg_.certificate_id[2], 3); + + assign(test_msg_.certificate_id[3], 4); + assign(test_msg_.flags, 0); + assign(test_msg_.n_signed_messages, 184); + assign(test_msg_.on_demand_counter, 2); + + assign(test_msg_.signature[0], 0); + + assign(test_msg_.signature[1], 1); + + assign(test_msg_.signature[2], 2); + + assign(test_msg_.signature[3], 3); + + assign(test_msg_.signature[4], 4); + + assign(test_msg_.signature[5], 5); - sbp_msg_ecdsa_signature_dep_a_t test_msg{}; + assign(test_msg_.signature[6], 6); - test_msg.certificate_id[0] = 1; + assign(test_msg_.signature[7], 7); - test_msg.certificate_id[1] = 2; + assign(test_msg_.signature[8], 0); - test_msg.certificate_id[2] = 3; + assign(test_msg_.signature[9], 1); - test_msg.certificate_id[3] = 4; - test_msg.flags = 0; - test_msg.n_signed_messages = 184; - test_msg.on_demand_counter = 2; + assign(test_msg_.signature[10], 2); - test_msg.signature[0] = 0; + assign(test_msg_.signature[11], 3); - test_msg.signature[1] = 1; + assign(test_msg_.signature[12], 4); - test_msg.signature[2] = 2; + assign(test_msg_.signature[13], 5); - test_msg.signature[3] = 3; + assign(test_msg_.signature[14], 6); - test_msg.signature[4] = 4; + assign(test_msg_.signature[15], 7); - test_msg.signature[5] = 5; + assign(test_msg_.signature[16], 0); - test_msg.signature[6] = 6; + assign(test_msg_.signature[17], 1); - test_msg.signature[7] = 7; + assign(test_msg_.signature[18], 2); - test_msg.signature[8] = 0; + assign(test_msg_.signature[19], 3); - test_msg.signature[9] = 1; + assign(test_msg_.signature[20], 4); - test_msg.signature[10] = 2; + assign(test_msg_.signature[21], 5); - test_msg.signature[11] = 3; + assign(test_msg_.signature[22], 6); - test_msg.signature[12] = 4; + assign(test_msg_.signature[23], 7); - test_msg.signature[13] = 5; + assign(test_msg_.signature[24], 0); - test_msg.signature[14] = 6; + assign(test_msg_.signature[25], 1); - test_msg.signature[15] = 7; + assign(test_msg_.signature[26], 2); - test_msg.signature[16] = 0; + assign(test_msg_.signature[27], 3); - test_msg.signature[17] = 1; + assign(test_msg_.signature[28], 4); - test_msg.signature[18] = 2; + assign(test_msg_.signature[29], 5); - test_msg.signature[19] = 3; + assign(test_msg_.signature[30], 6); - test_msg.signature[20] = 4; + assign(test_msg_.signature[31], 7); - test_msg.signature[21] = 5; + assign(test_msg_.signature[32], 0); - test_msg.signature[22] = 6; + assign(test_msg_.signature[33], 1); - test_msg.signature[23] = 7; + assign(test_msg_.signature[34], 2); - test_msg.signature[24] = 0; + assign(test_msg_.signature[35], 3); - test_msg.signature[25] = 1; + assign(test_msg_.signature[36], 4); - test_msg.signature[26] = 2; + assign(test_msg_.signature[37], 5); - test_msg.signature[27] = 3; + assign(test_msg_.signature[38], 6); - test_msg.signature[28] = 4; + assign(test_msg_.signature[39], 7); - test_msg.signature[29] = 5; + assign(test_msg_.signature[40], 0); - test_msg.signature[30] = 6; + assign(test_msg_.signature[41], 1); - test_msg.signature[31] = 7; + assign(test_msg_.signature[42], 2); - test_msg.signature[32] = 0; + assign(test_msg_.signature[43], 3); - test_msg.signature[33] = 1; + assign(test_msg_.signature[44], 4); - test_msg.signature[34] = 2; + assign(test_msg_.signature[45], 5); - test_msg.signature[35] = 3; + assign(test_msg_.signature[46], 6); - test_msg.signature[36] = 4; + assign(test_msg_.signature[47], 7); - test_msg.signature[37] = 5; + assign(test_msg_.signature[48], 0); - test_msg.signature[38] = 6; + assign(test_msg_.signature[49], 1); - test_msg.signature[39] = 7; + assign(test_msg_.signature[50], 2); - test_msg.signature[40] = 0; + assign(test_msg_.signature[51], 3); - test_msg.signature[41] = 1; + assign(test_msg_.signature[52], 4); - test_msg.signature[42] = 2; + assign(test_msg_.signature[53], 5); - test_msg.signature[43] = 3; + assign(test_msg_.signature[54], 6); - test_msg.signature[44] = 4; + assign(test_msg_.signature[55], 7); - test_msg.signature[45] = 5; + assign(test_msg_.signature[56], 0); - test_msg.signature[46] = 6; + assign(test_msg_.signature[57], 1); - test_msg.signature[47] = 7; + assign(test_msg_.signature[58], 2); - test_msg.signature[48] = 0; + assign(test_msg_.signature[59], 3); - test_msg.signature[49] = 1; + assign(test_msg_.signature[60], 4); - test_msg.signature[50] = 2; + assign(test_msg_.signature[61], 5); - test_msg.signature[51] = 3; + assign(test_msg_.signature[62], 6); - test_msg.signature[52] = 4; + assign(test_msg_.signature[63], 7); - test_msg.signature[53] = 5; + assign(test_msg_.signed_messages[0], 10); - test_msg.signature[54] = 6; + assign(test_msg_.signed_messages[1], 21); - test_msg.signature[55] = 7; + assign(test_msg_.signed_messages[2], 23); - test_msg.signature[56] = 0; + assign(test_msg_.signed_messages[3], 63); - test_msg.signature[57] = 1; + assign(test_msg_.signed_messages[4], 140); - test_msg.signature[58] = 2; + assign(test_msg_.signed_messages[5], 37); - test_msg.signature[59] = 3; + assign(test_msg_.signed_messages[6], 130); - test_msg.signature[60] = 4; + assign(test_msg_.signed_messages[7], 106); - test_msg.signature[61] = 5; + assign(test_msg_.signed_messages[8], 28); - test_msg.signature[62] = 6; + assign(test_msg_.signed_messages[9], 40); - test_msg.signature[63] = 7; + assign(test_msg_.signed_messages[10], 165); - test_msg.signed_messages[0] = 10; + assign(test_msg_.signed_messages[11], 179); - test_msg.signed_messages[1] = 21; + assign(test_msg_.signed_messages[12], 73); - test_msg.signed_messages[2] = 23; + assign(test_msg_.signed_messages[13], 178); - test_msg.signed_messages[3] = 63; + assign(test_msg_.signed_messages[14], 60); - test_msg.signed_messages[4] = 140; + assign(test_msg_.signed_messages[15], 126); - test_msg.signed_messages[5] = 37; + assign(test_msg_.signed_messages[16], 114); - test_msg.signed_messages[6] = 130; + assign(test_msg_.signed_messages[17], 78); - test_msg.signed_messages[7] = 106; + assign(test_msg_.signed_messages[18], 113); - test_msg.signed_messages[8] = 28; + assign(test_msg_.signed_messages[19], 27); - test_msg.signed_messages[9] = 40; + assign(test_msg_.signed_messages[20], 95); - test_msg.signed_messages[10] = 165; + assign(test_msg_.signed_messages[21], 3); - test_msg.signed_messages[11] = 179; + assign(test_msg_.signed_messages[22], 62); - test_msg.signed_messages[12] = 73; + assign(test_msg_.signed_messages[23], 104); - test_msg.signed_messages[13] = 178; + assign(test_msg_.signed_messages[24], 145); - test_msg.signed_messages[14] = 60; + assign(test_msg_.signed_messages[25], 96); - test_msg.signed_messages[15] = 126; + assign(test_msg_.signed_messages[26], 19); - test_msg.signed_messages[16] = 114; + assign(test_msg_.signed_messages[27], 92); - test_msg.signed_messages[17] = 78; + assign(test_msg_.signed_messages[28], 123); - test_msg.signed_messages[18] = 113; + assign(test_msg_.signed_messages[29], 14); - test_msg.signed_messages[19] = 27; + assign(test_msg_.signed_messages[30], 90); - test_msg.signed_messages[20] = 95; + assign(test_msg_.signed_messages[31], 153); - test_msg.signed_messages[21] = 3; + assign(test_msg_.signed_messages[32], 183); - test_msg.signed_messages[22] = 62; + assign(test_msg_.signed_messages[33], 9); - test_msg.signed_messages[23] = 104; + assign(test_msg_.signed_messages[34], 72); - test_msg.signed_messages[24] = 145; + assign(test_msg_.signed_messages[35], 81); - test_msg.signed_messages[25] = 96; + assign(test_msg_.signed_messages[36], 118); - test_msg.signed_messages[26] = 19; + assign(test_msg_.signed_messages[37], 112); - test_msg.signed_messages[27] = 92; + assign(test_msg_.signed_messages[38], 124); - test_msg.signed_messages[28] = 123; + assign(test_msg_.signed_messages[39], 16); - test_msg.signed_messages[29] = 14; + assign(test_msg_.signed_messages[40], 182); - test_msg.signed_messages[30] = 90; + assign(test_msg_.signed_messages[41], 76); - test_msg.signed_messages[31] = 153; + assign(test_msg_.signed_messages[42], 146); - test_msg.signed_messages[32] = 183; + assign(test_msg_.signed_messages[43], 115); - test_msg.signed_messages[33] = 9; + assign(test_msg_.signed_messages[44], 58); - test_msg.signed_messages[34] = 72; + assign(test_msg_.signed_messages[45], 144); - test_msg.signed_messages[35] = 81; + assign(test_msg_.signed_messages[46], 17); - test_msg.signed_messages[36] = 118; + assign(test_msg_.signed_messages[47], 105); - test_msg.signed_messages[37] = 112; + assign(test_msg_.signed_messages[48], 66); - test_msg.signed_messages[38] = 124; + assign(test_msg_.signed_messages[49], 31); - test_msg.signed_messages[39] = 16; + assign(test_msg_.signed_messages[50], 135); - test_msg.signed_messages[40] = 182; + assign(test_msg_.signed_messages[51], 54); - test_msg.signed_messages[41] = 76; + assign(test_msg_.signed_messages[52], 100); - test_msg.signed_messages[42] = 146; + assign(test_msg_.signed_messages[53], 84); - test_msg.signed_messages[43] = 115; + assign(test_msg_.signed_messages[54], 181); - test_msg.signed_messages[44] = 58; + assign(test_msg_.signed_messages[55], 103); - test_msg.signed_messages[45] = 144; + assign(test_msg_.signed_messages[56], 11); - test_msg.signed_messages[46] = 17; + assign(test_msg_.signed_messages[57], 88); - test_msg.signed_messages[47] = 105; + assign(test_msg_.signed_messages[58], 133); - test_msg.signed_messages[48] = 66; + assign(test_msg_.signed_messages[59], 155); - test_msg.signed_messages[49] = 31; + assign(test_msg_.signed_messages[60], 167); - test_msg.signed_messages[50] = 135; + assign(test_msg_.signed_messages[61], 173); - test_msg.signed_messages[51] = 54; + assign(test_msg_.signed_messages[62], 143); - test_msg.signed_messages[52] = 100; + assign(test_msg_.signed_messages[63], 86); - test_msg.signed_messages[53] = 84; + assign(test_msg_.signed_messages[64], 158); - test_msg.signed_messages[54] = 181; + assign(test_msg_.signed_messages[65], 20); - test_msg.signed_messages[55] = 103; + assign(test_msg_.signed_messages[66], 168); - test_msg.signed_messages[56] = 11; + assign(test_msg_.signed_messages[67], 132); - test_msg.signed_messages[57] = 88; + assign(test_msg_.signed_messages[68], 141); - test_msg.signed_messages[58] = 133; + assign(test_msg_.signed_messages[69], 102); - test_msg.signed_messages[59] = 155; + assign(test_msg_.signed_messages[70], 50); - test_msg.signed_messages[60] = 167; + assign(test_msg_.signed_messages[71], 48); - test_msg.signed_messages[61] = 173; + assign(test_msg_.signed_messages[72], 71); - test_msg.signed_messages[62] = 143; + assign(test_msg_.signed_messages[73], 147); - test_msg.signed_messages[63] = 86; + assign(test_msg_.signed_messages[74], 53); - test_msg.signed_messages[64] = 158; + assign(test_msg_.signed_messages[75], 87); - test_msg.signed_messages[65] = 20; + assign(test_msg_.signed_messages[76], 1); - test_msg.signed_messages[66] = 168; + assign(test_msg_.signed_messages[77], 108); - test_msg.signed_messages[67] = 132; + assign(test_msg_.signed_messages[78], 138); - test_msg.signed_messages[68] = 141; + assign(test_msg_.signed_messages[79], 36); - test_msg.signed_messages[69] = 102; + assign(test_msg_.signed_messages[80], 134); - test_msg.signed_messages[70] = 50; + assign(test_msg_.signed_messages[81], 139); - test_msg.signed_messages[71] = 48; + assign(test_msg_.signed_messages[82], 163); - test_msg.signed_messages[72] = 71; + assign(test_msg_.signed_messages[83], 82); - test_msg.signed_messages[73] = 147; + assign(test_msg_.signed_messages[84], 43); - test_msg.signed_messages[74] = 53; + assign(test_msg_.signed_messages[85], 52); - test_msg.signed_messages[75] = 87; + assign(test_msg_.signed_messages[86], 150); - test_msg.signed_messages[76] = 1; + assign(test_msg_.signed_messages[87], 12); - test_msg.signed_messages[77] = 108; + assign(test_msg_.signed_messages[88], 30); - test_msg.signed_messages[78] = 138; + assign(test_msg_.signed_messages[89], 110); - test_msg.signed_messages[79] = 36; + assign(test_msg_.signed_messages[90], 156); - test_msg.signed_messages[80] = 134; + assign(test_msg_.signed_messages[91], 107); - test_msg.signed_messages[81] = 139; + assign(test_msg_.signed_messages[92], 120); - test_msg.signed_messages[82] = 163; + assign(test_msg_.signed_messages[93], 91); - test_msg.signed_messages[83] = 82; + assign(test_msg_.signed_messages[94], 122); - test_msg.signed_messages[84] = 43; + assign(test_msg_.signed_messages[95], 69); - test_msg.signed_messages[85] = 52; + assign(test_msg_.signed_messages[96], 164); - test_msg.signed_messages[86] = 150; + assign(test_msg_.signed_messages[97], 170); - test_msg.signed_messages[87] = 12; + assign(test_msg_.signed_messages[98], 116); - test_msg.signed_messages[88] = 30; + assign(test_msg_.signed_messages[99], 25); - test_msg.signed_messages[89] = 110; + assign(test_msg_.signed_messages[100], 94); - test_msg.signed_messages[90] = 156; + assign(test_msg_.signed_messages[101], 5); - test_msg.signed_messages[91] = 107; + assign(test_msg_.signed_messages[102], 22); - test_msg.signed_messages[92] = 120; + assign(test_msg_.signed_messages[103], 24); - test_msg.signed_messages[93] = 91; + assign(test_msg_.signed_messages[104], 162); - test_msg.signed_messages[94] = 122; + assign(test_msg_.signed_messages[105], 175); - test_msg.signed_messages[95] = 69; + assign(test_msg_.signed_messages[106], 38); - test_msg.signed_messages[96] = 164; + assign(test_msg_.signed_messages[107], 157); - test_msg.signed_messages[97] = 170; + assign(test_msg_.signed_messages[108], 98); - test_msg.signed_messages[98] = 116; + assign(test_msg_.signed_messages[109], 44); - test_msg.signed_messages[99] = 25; + assign(test_msg_.signed_messages[110], 160); - test_msg.signed_messages[100] = 94; + assign(test_msg_.signed_messages[111], 47); - test_msg.signed_messages[101] = 5; + assign(test_msg_.signed_messages[112], 97); - test_msg.signed_messages[102] = 22; + assign(test_msg_.signed_messages[113], 142); - test_msg.signed_messages[103] = 24; + assign(test_msg_.signed_messages[114], 8); - test_msg.signed_messages[104] = 162; + assign(test_msg_.signed_messages[115], 74); - test_msg.signed_messages[105] = 175; + assign(test_msg_.signed_messages[116], 13); - test_msg.signed_messages[106] = 38; + assign(test_msg_.signed_messages[117], 177); - test_msg.signed_messages[107] = 157; + assign(test_msg_.signed_messages[118], 15); - test_msg.signed_messages[108] = 98; + assign(test_msg_.signed_messages[119], 128); - test_msg.signed_messages[109] = 44; + assign(test_msg_.signed_messages[120], 26); - test_msg.signed_messages[110] = 160; + assign(test_msg_.signed_messages[121], 131); - test_msg.signed_messages[111] = 47; + assign(test_msg_.signed_messages[122], 154); - test_msg.signed_messages[112] = 97; + assign(test_msg_.signed_messages[123], 65); - test_msg.signed_messages[113] = 142; + assign(test_msg_.signed_messages[124], 169); - test_msg.signed_messages[114] = 8; + assign(test_msg_.signed_messages[125], 55); - test_msg.signed_messages[115] = 74; + assign(test_msg_.signed_messages[126], 136); - test_msg.signed_messages[116] = 13; + assign(test_msg_.signed_messages[127], 125); - test_msg.signed_messages[117] = 177; + assign(test_msg_.signed_messages[128], 171); - test_msg.signed_messages[118] = 15; + assign(test_msg_.signed_messages[129], 161); - test_msg.signed_messages[119] = 128; + assign(test_msg_.signed_messages[130], 29); - test_msg.signed_messages[120] = 26; + assign(test_msg_.signed_messages[131], 129); - test_msg.signed_messages[121] = 131; + assign(test_msg_.signed_messages[132], 151); - test_msg.signed_messages[122] = 154; + assign(test_msg_.signed_messages[133], 68); - test_msg.signed_messages[123] = 65; + assign(test_msg_.signed_messages[134], 166); - test_msg.signed_messages[124] = 169; + assign(test_msg_.signed_messages[135], 51); - test_msg.signed_messages[125] = 55; + assign(test_msg_.signed_messages[136], 70); - test_msg.signed_messages[126] = 136; + assign(test_msg_.signed_messages[137], 45); - test_msg.signed_messages[127] = 125; + assign(test_msg_.signed_messages[138], 56); - test_msg.signed_messages[128] = 171; + assign(test_msg_.signed_messages[139], 79); - test_msg.signed_messages[129] = 161; + assign(test_msg_.signed_messages[140], 149); - test_msg.signed_messages[130] = 29; + assign(test_msg_.signed_messages[141], 99); - test_msg.signed_messages[131] = 129; + assign(test_msg_.signed_messages[142], 42); - test_msg.signed_messages[132] = 151; + assign(test_msg_.signed_messages[143], 101); - test_msg.signed_messages[133] = 68; + assign(test_msg_.signed_messages[144], 152); - test_msg.signed_messages[134] = 166; + assign(test_msg_.signed_messages[145], 39); - test_msg.signed_messages[135] = 51; + assign(test_msg_.signed_messages[146], 89); - test_msg.signed_messages[136] = 70; + assign(test_msg_.signed_messages[147], 180); - test_msg.signed_messages[137] = 45; + assign(test_msg_.signed_messages[148], 64); - test_msg.signed_messages[138] = 56; + assign(test_msg_.signed_messages[149], 49); - test_msg.signed_messages[139] = 79; + assign(test_msg_.signed_messages[150], 6); - test_msg.signed_messages[140] = 149; + assign(test_msg_.signed_messages[151], 80); - test_msg.signed_messages[141] = 99; + assign(test_msg_.signed_messages[152], 172); - test_msg.signed_messages[142] = 42; + assign(test_msg_.signed_messages[153], 32); - test_msg.signed_messages[143] = 101; + assign(test_msg_.signed_messages[154], 109); - test_msg.signed_messages[144] = 152; + assign(test_msg_.signed_messages[155], 2); - test_msg.signed_messages[145] = 39; + assign(test_msg_.signed_messages[156], 119); - test_msg.signed_messages[146] = 89; + assign(test_msg_.signed_messages[157], 93); - test_msg.signed_messages[147] = 180; + assign(test_msg_.signed_messages[158], 176); - test_msg.signed_messages[148] = 64; + assign(test_msg_.signed_messages[159], 0); - test_msg.signed_messages[149] = 49; + assign(test_msg_.signed_messages[160], 33); - test_msg.signed_messages[150] = 6; + assign(test_msg_.signed_messages[161], 57); - test_msg.signed_messages[151] = 80; + assign(test_msg_.signed_messages[162], 34); - test_msg.signed_messages[152] = 172; + assign(test_msg_.signed_messages[163], 18); - test_msg.signed_messages[153] = 32; + assign(test_msg_.signed_messages[164], 85); - test_msg.signed_messages[154] = 109; + assign(test_msg_.signed_messages[165], 121); - test_msg.signed_messages[155] = 2; + assign(test_msg_.signed_messages[166], 137); - test_msg.signed_messages[156] = 119; + assign(test_msg_.signed_messages[167], 83); - test_msg.signed_messages[157] = 93; + assign(test_msg_.signed_messages[168], 111); - test_msg.signed_messages[158] = 176; + assign(test_msg_.signed_messages[169], 59); - test_msg.signed_messages[159] = 0; + assign(test_msg_.signed_messages[170], 7); - test_msg.signed_messages[160] = 33; + assign(test_msg_.signed_messages[171], 77); - test_msg.signed_messages[161] = 57; + assign(test_msg_.signed_messages[172], 4); - test_msg.signed_messages[162] = 34; + assign(test_msg_.signed_messages[173], 117); - test_msg.signed_messages[163] = 18; + assign(test_msg_.signed_messages[174], 159); - test_msg.signed_messages[164] = 85; + assign(test_msg_.signed_messages[175], 148); - test_msg.signed_messages[165] = 121; + assign(test_msg_.signed_messages[176], 35); - test_msg.signed_messages[166] = 137; + assign(test_msg_.signed_messages[177], 61); - test_msg.signed_messages[167] = 83; + assign(test_msg_.signed_messages[178], 41); - test_msg.signed_messages[168] = 111; + assign(test_msg_.signed_messages[179], 67); - test_msg.signed_messages[169] = 59; + assign(test_msg_.signed_messages[180], 46); - test_msg.signed_messages[170] = 7; + assign(test_msg_.signed_messages[181], 127); - test_msg.signed_messages[171] = 77; + assign(test_msg_.signed_messages[182], 75); - test_msg.signed_messages[172] = 4; + assign(test_msg_.signed_messages[183], 174); + assign(test_msg_.stream_counter, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ecdsa_signature_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEcdsaSignatureDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEcdsaSignatureDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ecdsa_signature_dep_a, + sizeof(msg->ecdsa_signature_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ecdsa_signature_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ecdsa_signature_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEcdsaSignatureDepA); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xAC61; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 255; + + return info; + } - test_msg.signed_messages[173] = 117; + protected: + void comparison_tests(const sbp_msg_ecdsa_signature_dep_a_t &lesser, + const sbp_msg_ecdsa_signature_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ecdsa_signature_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ecdsa_signature_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaSignatureDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaSignatureDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEcdsaSignatureDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEcdsaSignatureDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } - test_msg.signed_messages[174] = 159; + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ecdsa_signature_dep_a_t test_msg_{}; + uint8_t encoded_frame_[255 + 8] = { + 85, 6, 12, 66, 0, 255, 0, 1, 2, 1, 2, 3, 4, 0, 1, + 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, + 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, + 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, + 6, 7, 10, 21, 23, 63, 140, 37, 130, 106, 28, 40, 165, 179, 73, + 178, 60, 126, 114, 78, 113, 27, 95, 3, 62, 104, 145, 96, 19, 92, + 123, 14, 90, 153, 183, 9, 72, 81, 118, 112, 124, 16, 182, 76, 146, + 115, 58, 144, 17, 105, 66, 31, 135, 54, 100, 84, 181, 103, 11, 88, + 133, 155, 167, 173, 143, 86, 158, 20, 168, 132, 141, 102, 50, 48, 71, + 147, 53, 87, 1, 108, 138, 36, 134, 139, 163, 82, 43, 52, 150, 12, + 30, 110, 156, 107, 120, 91, 122, 69, 164, 170, 116, 25, 94, 5, 22, + 24, 162, 175, 38, 157, 98, 44, 160, 47, 97, 142, 8, 74, 13, 177, + 15, 128, 26, 131, 154, 65, 169, 55, 136, 125, 171, 161, 29, 129, 151, + 68, 166, 51, 70, 45, 56, 79, 149, 99, 42, 101, 152, 39, 89, 180, + 64, 49, 6, 80, 172, 32, 109, 2, 119, 93, 176, 0, 33, 57, 34, + 18, 85, 121, 137, 83, 111, 59, 7, 77, 4, 117, 159, 148, 35, 61, + 41, 67, 46, 127, 75, 174, 97, 172, + }; + uint8_t encoded_payload_[255] = { + 0, 1, 2, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, + 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, + 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, + 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, + 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7, 10, 21, 23, 63, + 140, 37, 130, 106, 28, 40, 165, 179, 73, 178, 60, 126, 114, 78, 113, + 27, 95, 3, 62, 104, 145, 96, 19, 92, 123, 14, 90, 153, 183, 9, + 72, 81, 118, 112, 124, 16, 182, 76, 146, 115, 58, 144, 17, 105, 66, + 31, 135, 54, 100, 84, 181, 103, 11, 88, 133, 155, 167, 173, 143, 86, + 158, 20, 168, 132, 141, 102, 50, 48, 71, 147, 53, 87, 1, 108, 138, + 36, 134, 139, 163, 82, 43, 52, 150, 12, 30, 110, 156, 107, 120, 91, + 122, 69, 164, 170, 116, 25, 94, 5, 22, 24, 162, 175, 38, 157, 98, + 44, 160, 47, 97, 142, 8, 74, 13, 177, 15, 128, 26, 131, 154, 65, + 169, 55, 136, 125, 171, 161, 29, 129, 151, 68, 166, 51, 70, 45, 56, + 79, 149, 99, 42, 101, 152, 39, 89, 180, 64, 49, 6, 80, 172, 32, + 109, 2, 119, 93, 176, 0, 33, 57, 34, 18, 85, 121, 137, 83, 111, + 59, 7, 77, 4, 117, 159, 148, 35, 61, 41, 67, 46, 127, 75, 174, + }; +}; - test_msg.signed_messages[175] = 148; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_encoded_len(&info.test_msg), + info.payload_len); - test_msg.signed_messages[176] = 35; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEcdsaSignatureDepA, &info.test_msg_wrapped), + info.payload_len); +} - test_msg.signed_messages[177] = 61; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[255]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 255); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 255), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEcdsaSignatureDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 255); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 255), 0); +} - test_msg.signed_messages[178] = 41; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[255]; - test_msg.signed_messages[179] = 67; + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 255), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[255]; + + for (uint8_t i = 0; i < 255; i++) { + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.signed_messages[180] = 46; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 255); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEcdsaSignatureDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 255); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signed_messages[181] = 127; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_a_t msg{}; - test_msg.signed_messages[182] = 75; + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ecdsa_signature_dep_a_t t{}; + return sbp_msg_ecdsa_signature_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ecdsa_signature_dep_a_t t{}; + t.n_signed_messages = 1; + return sbp_msg_ecdsa_signature_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} - test_msg.signed_messages[183] = 174; - test_msg.stream_counter = 1; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.certificate_id[0], 1) - << "incorrect value for last_msg_.certificate_id[0], expected 1, is " - << last_msg_.certificate_id[0]; - EXPECT_EQ(last_msg_.certificate_id[1], 2) - << "incorrect value for last_msg_.certificate_id[1], expected 2, is " - << last_msg_.certificate_id[1]; - EXPECT_EQ(last_msg_.certificate_id[2], 3) - << "incorrect value for last_msg_.certificate_id[2], expected 3, is " - << last_msg_.certificate_id[2]; - EXPECT_EQ(last_msg_.certificate_id[3], 4) - << "incorrect value for last_msg_.certificate_id[3], expected 4, is " - << last_msg_.certificate_id[3]; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_signed_messages, 184) - << "incorrect value for last_msg_.n_signed_messages, expected 184, is " - << last_msg_.n_signed_messages; - EXPECT_EQ(last_msg_.on_demand_counter, 2) - << "incorrect value for last_msg_.on_demand_counter, expected 2, is " - << last_msg_.on_demand_counter; - EXPECT_EQ(last_msg_.signature[0], 0) - << "incorrect value for last_msg_.signature[0], expected 0, is " - << last_msg_.signature[0]; - EXPECT_EQ(last_msg_.signature[1], 1) - << "incorrect value for last_msg_.signature[1], expected 1, is " - << last_msg_.signature[1]; - EXPECT_EQ(last_msg_.signature[2], 2) - << "incorrect value for last_msg_.signature[2], expected 2, is " - << last_msg_.signature[2]; - EXPECT_EQ(last_msg_.signature[3], 3) - << "incorrect value for last_msg_.signature[3], expected 3, is " - << last_msg_.signature[3]; - EXPECT_EQ(last_msg_.signature[4], 4) - << "incorrect value for last_msg_.signature[4], expected 4, is " - << last_msg_.signature[4]; - EXPECT_EQ(last_msg_.signature[5], 5) - << "incorrect value for last_msg_.signature[5], expected 5, is " - << last_msg_.signature[5]; - EXPECT_EQ(last_msg_.signature[6], 6) - << "incorrect value for last_msg_.signature[6], expected 6, is " - << last_msg_.signature[6]; - EXPECT_EQ(last_msg_.signature[7], 7) - << "incorrect value for last_msg_.signature[7], expected 7, is " - << last_msg_.signature[7]; - EXPECT_EQ(last_msg_.signature[8], 0) - << "incorrect value for last_msg_.signature[8], expected 0, is " - << last_msg_.signature[8]; - EXPECT_EQ(last_msg_.signature[9], 1) - << "incorrect value for last_msg_.signature[9], expected 1, is " - << last_msg_.signature[9]; - EXPECT_EQ(last_msg_.signature[10], 2) - << "incorrect value for last_msg_.signature[10], expected 2, is " - << last_msg_.signature[10]; - EXPECT_EQ(last_msg_.signature[11], 3) - << "incorrect value for last_msg_.signature[11], expected 3, is " - << last_msg_.signature[11]; - EXPECT_EQ(last_msg_.signature[12], 4) - << "incorrect value for last_msg_.signature[12], expected 4, is " - << last_msg_.signature[12]; - EXPECT_EQ(last_msg_.signature[13], 5) - << "incorrect value for last_msg_.signature[13], expected 5, is " - << last_msg_.signature[13]; - EXPECT_EQ(last_msg_.signature[14], 6) - << "incorrect value for last_msg_.signature[14], expected 6, is " - << last_msg_.signature[14]; - EXPECT_EQ(last_msg_.signature[15], 7) - << "incorrect value for last_msg_.signature[15], expected 7, is " - << last_msg_.signature[15]; - EXPECT_EQ(last_msg_.signature[16], 0) - << "incorrect value for last_msg_.signature[16], expected 0, is " - << last_msg_.signature[16]; - EXPECT_EQ(last_msg_.signature[17], 1) - << "incorrect value for last_msg_.signature[17], expected 1, is " - << last_msg_.signature[17]; - EXPECT_EQ(last_msg_.signature[18], 2) - << "incorrect value for last_msg_.signature[18], expected 2, is " - << last_msg_.signature[18]; - EXPECT_EQ(last_msg_.signature[19], 3) - << "incorrect value for last_msg_.signature[19], expected 3, is " - << last_msg_.signature[19]; - EXPECT_EQ(last_msg_.signature[20], 4) - << "incorrect value for last_msg_.signature[20], expected 4, is " - << last_msg_.signature[20]; - EXPECT_EQ(last_msg_.signature[21], 5) - << "incorrect value for last_msg_.signature[21], expected 5, is " - << last_msg_.signature[21]; - EXPECT_EQ(last_msg_.signature[22], 6) - << "incorrect value for last_msg_.signature[22], expected 6, is " - << last_msg_.signature[22]; - EXPECT_EQ(last_msg_.signature[23], 7) - << "incorrect value for last_msg_.signature[23], expected 7, is " - << last_msg_.signature[23]; - EXPECT_EQ(last_msg_.signature[24], 0) - << "incorrect value for last_msg_.signature[24], expected 0, is " - << last_msg_.signature[24]; - EXPECT_EQ(last_msg_.signature[25], 1) - << "incorrect value for last_msg_.signature[25], expected 1, is " - << last_msg_.signature[25]; - EXPECT_EQ(last_msg_.signature[26], 2) - << "incorrect value for last_msg_.signature[26], expected 2, is " - << last_msg_.signature[26]; - EXPECT_EQ(last_msg_.signature[27], 3) - << "incorrect value for last_msg_.signature[27], expected 3, is " - << last_msg_.signature[27]; - EXPECT_EQ(last_msg_.signature[28], 4) - << "incorrect value for last_msg_.signature[28], expected 4, is " - << last_msg_.signature[28]; - EXPECT_EQ(last_msg_.signature[29], 5) - << "incorrect value for last_msg_.signature[29], expected 5, is " - << last_msg_.signature[29]; - EXPECT_EQ(last_msg_.signature[30], 6) - << "incorrect value for last_msg_.signature[30], expected 6, is " - << last_msg_.signature[30]; - EXPECT_EQ(last_msg_.signature[31], 7) - << "incorrect value for last_msg_.signature[31], expected 7, is " - << last_msg_.signature[31]; - EXPECT_EQ(last_msg_.signature[32], 0) - << "incorrect value for last_msg_.signature[32], expected 0, is " - << last_msg_.signature[32]; - EXPECT_EQ(last_msg_.signature[33], 1) - << "incorrect value for last_msg_.signature[33], expected 1, is " - << last_msg_.signature[33]; - EXPECT_EQ(last_msg_.signature[34], 2) - << "incorrect value for last_msg_.signature[34], expected 2, is " - << last_msg_.signature[34]; - EXPECT_EQ(last_msg_.signature[35], 3) - << "incorrect value for last_msg_.signature[35], expected 3, is " - << last_msg_.signature[35]; - EXPECT_EQ(last_msg_.signature[36], 4) - << "incorrect value for last_msg_.signature[36], expected 4, is " - << last_msg_.signature[36]; - EXPECT_EQ(last_msg_.signature[37], 5) - << "incorrect value for last_msg_.signature[37], expected 5, is " - << last_msg_.signature[37]; - EXPECT_EQ(last_msg_.signature[38], 6) - << "incorrect value for last_msg_.signature[38], expected 6, is " - << last_msg_.signature[38]; - EXPECT_EQ(last_msg_.signature[39], 7) - << "incorrect value for last_msg_.signature[39], expected 7, is " - << last_msg_.signature[39]; - EXPECT_EQ(last_msg_.signature[40], 0) - << "incorrect value for last_msg_.signature[40], expected 0, is " - << last_msg_.signature[40]; - EXPECT_EQ(last_msg_.signature[41], 1) - << "incorrect value for last_msg_.signature[41], expected 1, is " - << last_msg_.signature[41]; - EXPECT_EQ(last_msg_.signature[42], 2) - << "incorrect value for last_msg_.signature[42], expected 2, is " - << last_msg_.signature[42]; - EXPECT_EQ(last_msg_.signature[43], 3) - << "incorrect value for last_msg_.signature[43], expected 3, is " - << last_msg_.signature[43]; - EXPECT_EQ(last_msg_.signature[44], 4) - << "incorrect value for last_msg_.signature[44], expected 4, is " - << last_msg_.signature[44]; - EXPECT_EQ(last_msg_.signature[45], 5) - << "incorrect value for last_msg_.signature[45], expected 5, is " - << last_msg_.signature[45]; - EXPECT_EQ(last_msg_.signature[46], 6) - << "incorrect value for last_msg_.signature[46], expected 6, is " - << last_msg_.signature[46]; - EXPECT_EQ(last_msg_.signature[47], 7) - << "incorrect value for last_msg_.signature[47], expected 7, is " - << last_msg_.signature[47]; - EXPECT_EQ(last_msg_.signature[48], 0) - << "incorrect value for last_msg_.signature[48], expected 0, is " - << last_msg_.signature[48]; - EXPECT_EQ(last_msg_.signature[49], 1) - << "incorrect value for last_msg_.signature[49], expected 1, is " - << last_msg_.signature[49]; - EXPECT_EQ(last_msg_.signature[50], 2) - << "incorrect value for last_msg_.signature[50], expected 2, is " - << last_msg_.signature[50]; - EXPECT_EQ(last_msg_.signature[51], 3) - << "incorrect value for last_msg_.signature[51], expected 3, is " - << last_msg_.signature[51]; - EXPECT_EQ(last_msg_.signature[52], 4) - << "incorrect value for last_msg_.signature[52], expected 4, is " - << last_msg_.signature[52]; - EXPECT_EQ(last_msg_.signature[53], 5) - << "incorrect value for last_msg_.signature[53], expected 5, is " - << last_msg_.signature[53]; - EXPECT_EQ(last_msg_.signature[54], 6) - << "incorrect value for last_msg_.signature[54], expected 6, is " - << last_msg_.signature[54]; - EXPECT_EQ(last_msg_.signature[55], 7) - << "incorrect value for last_msg_.signature[55], expected 7, is " - << last_msg_.signature[55]; - EXPECT_EQ(last_msg_.signature[56], 0) - << "incorrect value for last_msg_.signature[56], expected 0, is " - << last_msg_.signature[56]; - EXPECT_EQ(last_msg_.signature[57], 1) - << "incorrect value for last_msg_.signature[57], expected 1, is " - << last_msg_.signature[57]; - EXPECT_EQ(last_msg_.signature[58], 2) - << "incorrect value for last_msg_.signature[58], expected 2, is " - << last_msg_.signature[58]; - EXPECT_EQ(last_msg_.signature[59], 3) - << "incorrect value for last_msg_.signature[59], expected 3, is " - << last_msg_.signature[59]; - EXPECT_EQ(last_msg_.signature[60], 4) - << "incorrect value for last_msg_.signature[60], expected 4, is " - << last_msg_.signature[60]; - EXPECT_EQ(last_msg_.signature[61], 5) - << "incorrect value for last_msg_.signature[61], expected 5, is " - << last_msg_.signature[61]; - EXPECT_EQ(last_msg_.signature[62], 6) - << "incorrect value for last_msg_.signature[62], expected 6, is " - << last_msg_.signature[62]; - EXPECT_EQ(last_msg_.signature[63], 7) - << "incorrect value for last_msg_.signature[63], expected 7, is " - << last_msg_.signature[63]; - EXPECT_EQ(last_msg_.signed_messages[0], 10) - << "incorrect value for last_msg_.signed_messages[0], expected 10, is " - << last_msg_.signed_messages[0]; - EXPECT_EQ(last_msg_.signed_messages[1], 21) - << "incorrect value for last_msg_.signed_messages[1], expected 21, is " - << last_msg_.signed_messages[1]; - EXPECT_EQ(last_msg_.signed_messages[2], 23) - << "incorrect value for last_msg_.signed_messages[2], expected 23, is " - << last_msg_.signed_messages[2]; - EXPECT_EQ(last_msg_.signed_messages[3], 63) - << "incorrect value for last_msg_.signed_messages[3], expected 63, is " - << last_msg_.signed_messages[3]; - EXPECT_EQ(last_msg_.signed_messages[4], 140) - << "incorrect value for last_msg_.signed_messages[4], expected 140, is " - << last_msg_.signed_messages[4]; - EXPECT_EQ(last_msg_.signed_messages[5], 37) - << "incorrect value for last_msg_.signed_messages[5], expected 37, is " - << last_msg_.signed_messages[5]; - EXPECT_EQ(last_msg_.signed_messages[6], 130) - << "incorrect value for last_msg_.signed_messages[6], expected 130, is " - << last_msg_.signed_messages[6]; - EXPECT_EQ(last_msg_.signed_messages[7], 106) - << "incorrect value for last_msg_.signed_messages[7], expected 106, is " - << last_msg_.signed_messages[7]; - EXPECT_EQ(last_msg_.signed_messages[8], 28) - << "incorrect value for last_msg_.signed_messages[8], expected 28, is " - << last_msg_.signed_messages[8]; - EXPECT_EQ(last_msg_.signed_messages[9], 40) - << "incorrect value for last_msg_.signed_messages[9], expected 40, is " - << last_msg_.signed_messages[9]; - EXPECT_EQ(last_msg_.signed_messages[10], 165) - << "incorrect value for last_msg_.signed_messages[10], expected 165, is " - << last_msg_.signed_messages[10]; - EXPECT_EQ(last_msg_.signed_messages[11], 179) - << "incorrect value for last_msg_.signed_messages[11], expected 179, is " - << last_msg_.signed_messages[11]; - EXPECT_EQ(last_msg_.signed_messages[12], 73) - << "incorrect value for last_msg_.signed_messages[12], expected 73, is " - << last_msg_.signed_messages[12]; - EXPECT_EQ(last_msg_.signed_messages[13], 178) - << "incorrect value for last_msg_.signed_messages[13], expected 178, is " - << last_msg_.signed_messages[13]; - EXPECT_EQ(last_msg_.signed_messages[14], 60) - << "incorrect value for last_msg_.signed_messages[14], expected 60, is " - << last_msg_.signed_messages[14]; - EXPECT_EQ(last_msg_.signed_messages[15], 126) - << "incorrect value for last_msg_.signed_messages[15], expected 126, is " - << last_msg_.signed_messages[15]; - EXPECT_EQ(last_msg_.signed_messages[16], 114) - << "incorrect value for last_msg_.signed_messages[16], expected 114, is " - << last_msg_.signed_messages[16]; - EXPECT_EQ(last_msg_.signed_messages[17], 78) - << "incorrect value for last_msg_.signed_messages[17], expected 78, is " - << last_msg_.signed_messages[17]; - EXPECT_EQ(last_msg_.signed_messages[18], 113) - << "incorrect value for last_msg_.signed_messages[18], expected 113, is " - << last_msg_.signed_messages[18]; - EXPECT_EQ(last_msg_.signed_messages[19], 27) - << "incorrect value for last_msg_.signed_messages[19], expected 27, is " - << last_msg_.signed_messages[19]; - EXPECT_EQ(last_msg_.signed_messages[20], 95) - << "incorrect value for last_msg_.signed_messages[20], expected 95, is " - << last_msg_.signed_messages[20]; - EXPECT_EQ(last_msg_.signed_messages[21], 3) - << "incorrect value for last_msg_.signed_messages[21], expected 3, is " - << last_msg_.signed_messages[21]; - EXPECT_EQ(last_msg_.signed_messages[22], 62) - << "incorrect value for last_msg_.signed_messages[22], expected 62, is " - << last_msg_.signed_messages[22]; - EXPECT_EQ(last_msg_.signed_messages[23], 104) - << "incorrect value for last_msg_.signed_messages[23], expected 104, is " - << last_msg_.signed_messages[23]; - EXPECT_EQ(last_msg_.signed_messages[24], 145) - << "incorrect value for last_msg_.signed_messages[24], expected 145, is " - << last_msg_.signed_messages[24]; - EXPECT_EQ(last_msg_.signed_messages[25], 96) - << "incorrect value for last_msg_.signed_messages[25], expected 96, is " - << last_msg_.signed_messages[25]; - EXPECT_EQ(last_msg_.signed_messages[26], 19) - << "incorrect value for last_msg_.signed_messages[26], expected 19, is " - << last_msg_.signed_messages[26]; - EXPECT_EQ(last_msg_.signed_messages[27], 92) - << "incorrect value for last_msg_.signed_messages[27], expected 92, is " - << last_msg_.signed_messages[27]; - EXPECT_EQ(last_msg_.signed_messages[28], 123) - << "incorrect value for last_msg_.signed_messages[28], expected 123, is " - << last_msg_.signed_messages[28]; - EXPECT_EQ(last_msg_.signed_messages[29], 14) - << "incorrect value for last_msg_.signed_messages[29], expected 14, is " - << last_msg_.signed_messages[29]; - EXPECT_EQ(last_msg_.signed_messages[30], 90) - << "incorrect value for last_msg_.signed_messages[30], expected 90, is " - << last_msg_.signed_messages[30]; - EXPECT_EQ(last_msg_.signed_messages[31], 153) - << "incorrect value for last_msg_.signed_messages[31], expected 153, is " - << last_msg_.signed_messages[31]; - EXPECT_EQ(last_msg_.signed_messages[32], 183) - << "incorrect value for last_msg_.signed_messages[32], expected 183, is " - << last_msg_.signed_messages[32]; - EXPECT_EQ(last_msg_.signed_messages[33], 9) - << "incorrect value for last_msg_.signed_messages[33], expected 9, is " - << last_msg_.signed_messages[33]; - EXPECT_EQ(last_msg_.signed_messages[34], 72) - << "incorrect value for last_msg_.signed_messages[34], expected 72, is " - << last_msg_.signed_messages[34]; - EXPECT_EQ(last_msg_.signed_messages[35], 81) - << "incorrect value for last_msg_.signed_messages[35], expected 81, is " - << last_msg_.signed_messages[35]; - EXPECT_EQ(last_msg_.signed_messages[36], 118) - << "incorrect value for last_msg_.signed_messages[36], expected 118, is " - << last_msg_.signed_messages[36]; - EXPECT_EQ(last_msg_.signed_messages[37], 112) - << "incorrect value for last_msg_.signed_messages[37], expected 112, is " - << last_msg_.signed_messages[37]; - EXPECT_EQ(last_msg_.signed_messages[38], 124) - << "incorrect value for last_msg_.signed_messages[38], expected 124, is " - << last_msg_.signed_messages[38]; - EXPECT_EQ(last_msg_.signed_messages[39], 16) - << "incorrect value for last_msg_.signed_messages[39], expected 16, is " - << last_msg_.signed_messages[39]; - EXPECT_EQ(last_msg_.signed_messages[40], 182) - << "incorrect value for last_msg_.signed_messages[40], expected 182, is " - << last_msg_.signed_messages[40]; - EXPECT_EQ(last_msg_.signed_messages[41], 76) - << "incorrect value for last_msg_.signed_messages[41], expected 76, is " - << last_msg_.signed_messages[41]; - EXPECT_EQ(last_msg_.signed_messages[42], 146) - << "incorrect value for last_msg_.signed_messages[42], expected 146, is " - << last_msg_.signed_messages[42]; - EXPECT_EQ(last_msg_.signed_messages[43], 115) - << "incorrect value for last_msg_.signed_messages[43], expected 115, is " - << last_msg_.signed_messages[43]; - EXPECT_EQ(last_msg_.signed_messages[44], 58) - << "incorrect value for last_msg_.signed_messages[44], expected 58, is " - << last_msg_.signed_messages[44]; - EXPECT_EQ(last_msg_.signed_messages[45], 144) - << "incorrect value for last_msg_.signed_messages[45], expected 144, is " - << last_msg_.signed_messages[45]; - EXPECT_EQ(last_msg_.signed_messages[46], 17) - << "incorrect value for last_msg_.signed_messages[46], expected 17, is " - << last_msg_.signed_messages[46]; - EXPECT_EQ(last_msg_.signed_messages[47], 105) - << "incorrect value for last_msg_.signed_messages[47], expected 105, is " - << last_msg_.signed_messages[47]; - EXPECT_EQ(last_msg_.signed_messages[48], 66) - << "incorrect value for last_msg_.signed_messages[48], expected 66, is " - << last_msg_.signed_messages[48]; - EXPECT_EQ(last_msg_.signed_messages[49], 31) - << "incorrect value for last_msg_.signed_messages[49], expected 31, is " - << last_msg_.signed_messages[49]; - EXPECT_EQ(last_msg_.signed_messages[50], 135) - << "incorrect value for last_msg_.signed_messages[50], expected 135, is " - << last_msg_.signed_messages[50]; - EXPECT_EQ(last_msg_.signed_messages[51], 54) - << "incorrect value for last_msg_.signed_messages[51], expected 54, is " - << last_msg_.signed_messages[51]; - EXPECT_EQ(last_msg_.signed_messages[52], 100) - << "incorrect value for last_msg_.signed_messages[52], expected 100, is " - << last_msg_.signed_messages[52]; - EXPECT_EQ(last_msg_.signed_messages[53], 84) - << "incorrect value for last_msg_.signed_messages[53], expected 84, is " - << last_msg_.signed_messages[53]; - EXPECT_EQ(last_msg_.signed_messages[54], 181) - << "incorrect value for last_msg_.signed_messages[54], expected 181, is " - << last_msg_.signed_messages[54]; - EXPECT_EQ(last_msg_.signed_messages[55], 103) - << "incorrect value for last_msg_.signed_messages[55], expected 103, is " - << last_msg_.signed_messages[55]; - EXPECT_EQ(last_msg_.signed_messages[56], 11) - << "incorrect value for last_msg_.signed_messages[56], expected 11, is " - << last_msg_.signed_messages[56]; - EXPECT_EQ(last_msg_.signed_messages[57], 88) - << "incorrect value for last_msg_.signed_messages[57], expected 88, is " - << last_msg_.signed_messages[57]; - EXPECT_EQ(last_msg_.signed_messages[58], 133) - << "incorrect value for last_msg_.signed_messages[58], expected 133, is " - << last_msg_.signed_messages[58]; - EXPECT_EQ(last_msg_.signed_messages[59], 155) - << "incorrect value for last_msg_.signed_messages[59], expected 155, is " - << last_msg_.signed_messages[59]; - EXPECT_EQ(last_msg_.signed_messages[60], 167) - << "incorrect value for last_msg_.signed_messages[60], expected 167, is " - << last_msg_.signed_messages[60]; - EXPECT_EQ(last_msg_.signed_messages[61], 173) - << "incorrect value for last_msg_.signed_messages[61], expected 173, is " - << last_msg_.signed_messages[61]; - EXPECT_EQ(last_msg_.signed_messages[62], 143) - << "incorrect value for last_msg_.signed_messages[62], expected 143, is " - << last_msg_.signed_messages[62]; - EXPECT_EQ(last_msg_.signed_messages[63], 86) - << "incorrect value for last_msg_.signed_messages[63], expected 86, is " - << last_msg_.signed_messages[63]; - EXPECT_EQ(last_msg_.signed_messages[64], 158) - << "incorrect value for last_msg_.signed_messages[64], expected 158, is " - << last_msg_.signed_messages[64]; - EXPECT_EQ(last_msg_.signed_messages[65], 20) - << "incorrect value for last_msg_.signed_messages[65], expected 20, is " - << last_msg_.signed_messages[65]; - EXPECT_EQ(last_msg_.signed_messages[66], 168) - << "incorrect value for last_msg_.signed_messages[66], expected 168, is " - << last_msg_.signed_messages[66]; - EXPECT_EQ(last_msg_.signed_messages[67], 132) - << "incorrect value for last_msg_.signed_messages[67], expected 132, is " - << last_msg_.signed_messages[67]; - EXPECT_EQ(last_msg_.signed_messages[68], 141) - << "incorrect value for last_msg_.signed_messages[68], expected 141, is " - << last_msg_.signed_messages[68]; - EXPECT_EQ(last_msg_.signed_messages[69], 102) - << "incorrect value for last_msg_.signed_messages[69], expected 102, is " - << last_msg_.signed_messages[69]; - EXPECT_EQ(last_msg_.signed_messages[70], 50) - << "incorrect value for last_msg_.signed_messages[70], expected 50, is " - << last_msg_.signed_messages[70]; - EXPECT_EQ(last_msg_.signed_messages[71], 48) - << "incorrect value for last_msg_.signed_messages[71], expected 48, is " - << last_msg_.signed_messages[71]; - EXPECT_EQ(last_msg_.signed_messages[72], 71) - << "incorrect value for last_msg_.signed_messages[72], expected 71, is " - << last_msg_.signed_messages[72]; - EXPECT_EQ(last_msg_.signed_messages[73], 147) - << "incorrect value for last_msg_.signed_messages[73], expected 147, is " - << last_msg_.signed_messages[73]; - EXPECT_EQ(last_msg_.signed_messages[74], 53) - << "incorrect value for last_msg_.signed_messages[74], expected 53, is " - << last_msg_.signed_messages[74]; - EXPECT_EQ(last_msg_.signed_messages[75], 87) - << "incorrect value for last_msg_.signed_messages[75], expected 87, is " - << last_msg_.signed_messages[75]; - EXPECT_EQ(last_msg_.signed_messages[76], 1) - << "incorrect value for last_msg_.signed_messages[76], expected 1, is " - << last_msg_.signed_messages[76]; - EXPECT_EQ(last_msg_.signed_messages[77], 108) - << "incorrect value for last_msg_.signed_messages[77], expected 108, is " - << last_msg_.signed_messages[77]; - EXPECT_EQ(last_msg_.signed_messages[78], 138) - << "incorrect value for last_msg_.signed_messages[78], expected 138, is " - << last_msg_.signed_messages[78]; - EXPECT_EQ(last_msg_.signed_messages[79], 36) - << "incorrect value for last_msg_.signed_messages[79], expected 36, is " - << last_msg_.signed_messages[79]; - EXPECT_EQ(last_msg_.signed_messages[80], 134) - << "incorrect value for last_msg_.signed_messages[80], expected 134, is " - << last_msg_.signed_messages[80]; - EXPECT_EQ(last_msg_.signed_messages[81], 139) - << "incorrect value for last_msg_.signed_messages[81], expected 139, is " - << last_msg_.signed_messages[81]; - EXPECT_EQ(last_msg_.signed_messages[82], 163) - << "incorrect value for last_msg_.signed_messages[82], expected 163, is " - << last_msg_.signed_messages[82]; - EXPECT_EQ(last_msg_.signed_messages[83], 82) - << "incorrect value for last_msg_.signed_messages[83], expected 82, is " - << last_msg_.signed_messages[83]; - EXPECT_EQ(last_msg_.signed_messages[84], 43) - << "incorrect value for last_msg_.signed_messages[84], expected 43, is " - << last_msg_.signed_messages[84]; - EXPECT_EQ(last_msg_.signed_messages[85], 52) - << "incorrect value for last_msg_.signed_messages[85], expected 52, is " - << last_msg_.signed_messages[85]; - EXPECT_EQ(last_msg_.signed_messages[86], 150) - << "incorrect value for last_msg_.signed_messages[86], expected 150, is " - << last_msg_.signed_messages[86]; - EXPECT_EQ(last_msg_.signed_messages[87], 12) - << "incorrect value for last_msg_.signed_messages[87], expected 12, is " - << last_msg_.signed_messages[87]; - EXPECT_EQ(last_msg_.signed_messages[88], 30) - << "incorrect value for last_msg_.signed_messages[88], expected 30, is " - << last_msg_.signed_messages[88]; - EXPECT_EQ(last_msg_.signed_messages[89], 110) - << "incorrect value for last_msg_.signed_messages[89], expected 110, is " - << last_msg_.signed_messages[89]; - EXPECT_EQ(last_msg_.signed_messages[90], 156) - << "incorrect value for last_msg_.signed_messages[90], expected 156, is " - << last_msg_.signed_messages[90]; - EXPECT_EQ(last_msg_.signed_messages[91], 107) - << "incorrect value for last_msg_.signed_messages[91], expected 107, is " - << last_msg_.signed_messages[91]; - EXPECT_EQ(last_msg_.signed_messages[92], 120) - << "incorrect value for last_msg_.signed_messages[92], expected 120, is " - << last_msg_.signed_messages[92]; - EXPECT_EQ(last_msg_.signed_messages[93], 91) - << "incorrect value for last_msg_.signed_messages[93], expected 91, is " - << last_msg_.signed_messages[93]; - EXPECT_EQ(last_msg_.signed_messages[94], 122) - << "incorrect value for last_msg_.signed_messages[94], expected 122, is " - << last_msg_.signed_messages[94]; - EXPECT_EQ(last_msg_.signed_messages[95], 69) - << "incorrect value for last_msg_.signed_messages[95], expected 69, is " - << last_msg_.signed_messages[95]; - EXPECT_EQ(last_msg_.signed_messages[96], 164) - << "incorrect value for last_msg_.signed_messages[96], expected 164, is " - << last_msg_.signed_messages[96]; - EXPECT_EQ(last_msg_.signed_messages[97], 170) - << "incorrect value for last_msg_.signed_messages[97], expected 170, is " - << last_msg_.signed_messages[97]; - EXPECT_EQ(last_msg_.signed_messages[98], 116) - << "incorrect value for last_msg_.signed_messages[98], expected 116, is " - << last_msg_.signed_messages[98]; - EXPECT_EQ(last_msg_.signed_messages[99], 25) - << "incorrect value for last_msg_.signed_messages[99], expected 25, is " - << last_msg_.signed_messages[99]; - EXPECT_EQ(last_msg_.signed_messages[100], 94) - << "incorrect value for last_msg_.signed_messages[100], expected 94, is " - << last_msg_.signed_messages[100]; - EXPECT_EQ(last_msg_.signed_messages[101], 5) - << "incorrect value for last_msg_.signed_messages[101], expected 5, is " - << last_msg_.signed_messages[101]; - EXPECT_EQ(last_msg_.signed_messages[102], 22) - << "incorrect value for last_msg_.signed_messages[102], expected 22, is " - << last_msg_.signed_messages[102]; - EXPECT_EQ(last_msg_.signed_messages[103], 24) - << "incorrect value for last_msg_.signed_messages[103], expected 24, is " - << last_msg_.signed_messages[103]; - EXPECT_EQ(last_msg_.signed_messages[104], 162) - << "incorrect value for last_msg_.signed_messages[104], expected 162, is " - << last_msg_.signed_messages[104]; - EXPECT_EQ(last_msg_.signed_messages[105], 175) - << "incorrect value for last_msg_.signed_messages[105], expected 175, is " - << last_msg_.signed_messages[105]; - EXPECT_EQ(last_msg_.signed_messages[106], 38) - << "incorrect value for last_msg_.signed_messages[106], expected 38, is " - << last_msg_.signed_messages[106]; - EXPECT_EQ(last_msg_.signed_messages[107], 157) - << "incorrect value for last_msg_.signed_messages[107], expected 157, is " - << last_msg_.signed_messages[107]; - EXPECT_EQ(last_msg_.signed_messages[108], 98) - << "incorrect value for last_msg_.signed_messages[108], expected 98, is " - << last_msg_.signed_messages[108]; - EXPECT_EQ(last_msg_.signed_messages[109], 44) - << "incorrect value for last_msg_.signed_messages[109], expected 44, is " - << last_msg_.signed_messages[109]; - EXPECT_EQ(last_msg_.signed_messages[110], 160) - << "incorrect value for last_msg_.signed_messages[110], expected 160, is " - << last_msg_.signed_messages[110]; - EXPECT_EQ(last_msg_.signed_messages[111], 47) - << "incorrect value for last_msg_.signed_messages[111], expected 47, is " - << last_msg_.signed_messages[111]; - EXPECT_EQ(last_msg_.signed_messages[112], 97) - << "incorrect value for last_msg_.signed_messages[112], expected 97, is " - << last_msg_.signed_messages[112]; - EXPECT_EQ(last_msg_.signed_messages[113], 142) - << "incorrect value for last_msg_.signed_messages[113], expected 142, is " - << last_msg_.signed_messages[113]; - EXPECT_EQ(last_msg_.signed_messages[114], 8) - << "incorrect value for last_msg_.signed_messages[114], expected 8, is " - << last_msg_.signed_messages[114]; - EXPECT_EQ(last_msg_.signed_messages[115], 74) - << "incorrect value for last_msg_.signed_messages[115], expected 74, is " - << last_msg_.signed_messages[115]; - EXPECT_EQ(last_msg_.signed_messages[116], 13) - << "incorrect value for last_msg_.signed_messages[116], expected 13, is " - << last_msg_.signed_messages[116]; - EXPECT_EQ(last_msg_.signed_messages[117], 177) - << "incorrect value for last_msg_.signed_messages[117], expected 177, is " - << last_msg_.signed_messages[117]; - EXPECT_EQ(last_msg_.signed_messages[118], 15) - << "incorrect value for last_msg_.signed_messages[118], expected 15, is " - << last_msg_.signed_messages[118]; - EXPECT_EQ(last_msg_.signed_messages[119], 128) - << "incorrect value for last_msg_.signed_messages[119], expected 128, is " - << last_msg_.signed_messages[119]; - EXPECT_EQ(last_msg_.signed_messages[120], 26) - << "incorrect value for last_msg_.signed_messages[120], expected 26, is " - << last_msg_.signed_messages[120]; - EXPECT_EQ(last_msg_.signed_messages[121], 131) - << "incorrect value for last_msg_.signed_messages[121], expected 131, is " - << last_msg_.signed_messages[121]; - EXPECT_EQ(last_msg_.signed_messages[122], 154) - << "incorrect value for last_msg_.signed_messages[122], expected 154, is " - << last_msg_.signed_messages[122]; - EXPECT_EQ(last_msg_.signed_messages[123], 65) - << "incorrect value for last_msg_.signed_messages[123], expected 65, is " - << last_msg_.signed_messages[123]; - EXPECT_EQ(last_msg_.signed_messages[124], 169) - << "incorrect value for last_msg_.signed_messages[124], expected 169, is " - << last_msg_.signed_messages[124]; - EXPECT_EQ(last_msg_.signed_messages[125], 55) - << "incorrect value for last_msg_.signed_messages[125], expected 55, is " - << last_msg_.signed_messages[125]; - EXPECT_EQ(last_msg_.signed_messages[126], 136) - << "incorrect value for last_msg_.signed_messages[126], expected 136, is " - << last_msg_.signed_messages[126]; - EXPECT_EQ(last_msg_.signed_messages[127], 125) - << "incorrect value for last_msg_.signed_messages[127], expected 125, is " - << last_msg_.signed_messages[127]; - EXPECT_EQ(last_msg_.signed_messages[128], 171) - << "incorrect value for last_msg_.signed_messages[128], expected 171, is " - << last_msg_.signed_messages[128]; - EXPECT_EQ(last_msg_.signed_messages[129], 161) - << "incorrect value for last_msg_.signed_messages[129], expected 161, is " - << last_msg_.signed_messages[129]; - EXPECT_EQ(last_msg_.signed_messages[130], 29) - << "incorrect value for last_msg_.signed_messages[130], expected 29, is " - << last_msg_.signed_messages[130]; - EXPECT_EQ(last_msg_.signed_messages[131], 129) - << "incorrect value for last_msg_.signed_messages[131], expected 129, is " - << last_msg_.signed_messages[131]; - EXPECT_EQ(last_msg_.signed_messages[132], 151) - << "incorrect value for last_msg_.signed_messages[132], expected 151, is " - << last_msg_.signed_messages[132]; - EXPECT_EQ(last_msg_.signed_messages[133], 68) - << "incorrect value for last_msg_.signed_messages[133], expected 68, is " - << last_msg_.signed_messages[133]; - EXPECT_EQ(last_msg_.signed_messages[134], 166) - << "incorrect value for last_msg_.signed_messages[134], expected 166, is " - << last_msg_.signed_messages[134]; - EXPECT_EQ(last_msg_.signed_messages[135], 51) - << "incorrect value for last_msg_.signed_messages[135], expected 51, is " - << last_msg_.signed_messages[135]; - EXPECT_EQ(last_msg_.signed_messages[136], 70) - << "incorrect value for last_msg_.signed_messages[136], expected 70, is " - << last_msg_.signed_messages[136]; - EXPECT_EQ(last_msg_.signed_messages[137], 45) - << "incorrect value for last_msg_.signed_messages[137], expected 45, is " - << last_msg_.signed_messages[137]; - EXPECT_EQ(last_msg_.signed_messages[138], 56) - << "incorrect value for last_msg_.signed_messages[138], expected 56, is " - << last_msg_.signed_messages[138]; - EXPECT_EQ(last_msg_.signed_messages[139], 79) - << "incorrect value for last_msg_.signed_messages[139], expected 79, is " - << last_msg_.signed_messages[139]; - EXPECT_EQ(last_msg_.signed_messages[140], 149) - << "incorrect value for last_msg_.signed_messages[140], expected 149, is " - << last_msg_.signed_messages[140]; - EXPECT_EQ(last_msg_.signed_messages[141], 99) - << "incorrect value for last_msg_.signed_messages[141], expected 99, is " - << last_msg_.signed_messages[141]; - EXPECT_EQ(last_msg_.signed_messages[142], 42) - << "incorrect value for last_msg_.signed_messages[142], expected 42, is " - << last_msg_.signed_messages[142]; - EXPECT_EQ(last_msg_.signed_messages[143], 101) - << "incorrect value for last_msg_.signed_messages[143], expected 101, is " - << last_msg_.signed_messages[143]; - EXPECT_EQ(last_msg_.signed_messages[144], 152) - << "incorrect value for last_msg_.signed_messages[144], expected 152, is " - << last_msg_.signed_messages[144]; - EXPECT_EQ(last_msg_.signed_messages[145], 39) - << "incorrect value for last_msg_.signed_messages[145], expected 39, is " - << last_msg_.signed_messages[145]; - EXPECT_EQ(last_msg_.signed_messages[146], 89) - << "incorrect value for last_msg_.signed_messages[146], expected 89, is " - << last_msg_.signed_messages[146]; - EXPECT_EQ(last_msg_.signed_messages[147], 180) - << "incorrect value for last_msg_.signed_messages[147], expected 180, is " - << last_msg_.signed_messages[147]; - EXPECT_EQ(last_msg_.signed_messages[148], 64) - << "incorrect value for last_msg_.signed_messages[148], expected 64, is " - << last_msg_.signed_messages[148]; - EXPECT_EQ(last_msg_.signed_messages[149], 49) - << "incorrect value for last_msg_.signed_messages[149], expected 49, is " - << last_msg_.signed_messages[149]; - EXPECT_EQ(last_msg_.signed_messages[150], 6) - << "incorrect value for last_msg_.signed_messages[150], expected 6, is " - << last_msg_.signed_messages[150]; - EXPECT_EQ(last_msg_.signed_messages[151], 80) - << "incorrect value for last_msg_.signed_messages[151], expected 80, is " - << last_msg_.signed_messages[151]; - EXPECT_EQ(last_msg_.signed_messages[152], 172) - << "incorrect value for last_msg_.signed_messages[152], expected 172, is " - << last_msg_.signed_messages[152]; - EXPECT_EQ(last_msg_.signed_messages[153], 32) - << "incorrect value for last_msg_.signed_messages[153], expected 32, is " - << last_msg_.signed_messages[153]; - EXPECT_EQ(last_msg_.signed_messages[154], 109) - << "incorrect value for last_msg_.signed_messages[154], expected 109, is " - << last_msg_.signed_messages[154]; - EXPECT_EQ(last_msg_.signed_messages[155], 2) - << "incorrect value for last_msg_.signed_messages[155], expected 2, is " - << last_msg_.signed_messages[155]; - EXPECT_EQ(last_msg_.signed_messages[156], 119) - << "incorrect value for last_msg_.signed_messages[156], expected 119, is " - << last_msg_.signed_messages[156]; - EXPECT_EQ(last_msg_.signed_messages[157], 93) - << "incorrect value for last_msg_.signed_messages[157], expected 93, is " - << last_msg_.signed_messages[157]; - EXPECT_EQ(last_msg_.signed_messages[158], 176) - << "incorrect value for last_msg_.signed_messages[158], expected 176, is " - << last_msg_.signed_messages[158]; - EXPECT_EQ(last_msg_.signed_messages[159], 0) - << "incorrect value for last_msg_.signed_messages[159], expected 0, is " - << last_msg_.signed_messages[159]; - EXPECT_EQ(last_msg_.signed_messages[160], 33) - << "incorrect value for last_msg_.signed_messages[160], expected 33, is " - << last_msg_.signed_messages[160]; - EXPECT_EQ(last_msg_.signed_messages[161], 57) - << "incorrect value for last_msg_.signed_messages[161], expected 57, is " - << last_msg_.signed_messages[161]; - EXPECT_EQ(last_msg_.signed_messages[162], 34) - << "incorrect value for last_msg_.signed_messages[162], expected 34, is " - << last_msg_.signed_messages[162]; - EXPECT_EQ(last_msg_.signed_messages[163], 18) - << "incorrect value for last_msg_.signed_messages[163], expected 18, is " - << last_msg_.signed_messages[163]; - EXPECT_EQ(last_msg_.signed_messages[164], 85) - << "incorrect value for last_msg_.signed_messages[164], expected 85, is " - << last_msg_.signed_messages[164]; - EXPECT_EQ(last_msg_.signed_messages[165], 121) - << "incorrect value for last_msg_.signed_messages[165], expected 121, is " - << last_msg_.signed_messages[165]; - EXPECT_EQ(last_msg_.signed_messages[166], 137) - << "incorrect value for last_msg_.signed_messages[166], expected 137, is " - << last_msg_.signed_messages[166]; - EXPECT_EQ(last_msg_.signed_messages[167], 83) - << "incorrect value for last_msg_.signed_messages[167], expected 83, is " - << last_msg_.signed_messages[167]; - EXPECT_EQ(last_msg_.signed_messages[168], 111) - << "incorrect value for last_msg_.signed_messages[168], expected 111, is " - << last_msg_.signed_messages[168]; - EXPECT_EQ(last_msg_.signed_messages[169], 59) - << "incorrect value for last_msg_.signed_messages[169], expected 59, is " - << last_msg_.signed_messages[169]; - EXPECT_EQ(last_msg_.signed_messages[170], 7) - << "incorrect value for last_msg_.signed_messages[170], expected 7, is " - << last_msg_.signed_messages[170]; - EXPECT_EQ(last_msg_.signed_messages[171], 77) - << "incorrect value for last_msg_.signed_messages[171], expected 77, is " - << last_msg_.signed_messages[171]; - EXPECT_EQ(last_msg_.signed_messages[172], 4) - << "incorrect value for last_msg_.signed_messages[172], expected 4, is " - << last_msg_.signed_messages[172]; - EXPECT_EQ(last_msg_.signed_messages[173], 117) - << "incorrect value for last_msg_.signed_messages[173], expected 117, is " - << last_msg_.signed_messages[173]; - EXPECT_EQ(last_msg_.signed_messages[174], 159) - << "incorrect value for last_msg_.signed_messages[174], expected 159, is " - << last_msg_.signed_messages[174]; - EXPECT_EQ(last_msg_.signed_messages[175], 148) - << "incorrect value for last_msg_.signed_messages[175], expected 148, is " - << last_msg_.signed_messages[175]; - EXPECT_EQ(last_msg_.signed_messages[176], 35) - << "incorrect value for last_msg_.signed_messages[176], expected 35, is " - << last_msg_.signed_messages[176]; - EXPECT_EQ(last_msg_.signed_messages[177], 61) - << "incorrect value for last_msg_.signed_messages[177], expected 61, is " - << last_msg_.signed_messages[177]; - EXPECT_EQ(last_msg_.signed_messages[178], 41) - << "incorrect value for last_msg_.signed_messages[178], expected 41, is " - << last_msg_.signed_messages[178]; - EXPECT_EQ(last_msg_.signed_messages[179], 67) - << "incorrect value for last_msg_.signed_messages[179], expected 67, is " - << last_msg_.signed_messages[179]; - EXPECT_EQ(last_msg_.signed_messages[180], 46) - << "incorrect value for last_msg_.signed_messages[180], expected 46, is " - << last_msg_.signed_messages[180]; - EXPECT_EQ(last_msg_.signed_messages[181], 127) - << "incorrect value for last_msg_.signed_messages[181], expected 127, is " - << last_msg_.signed_messages[181]; - EXPECT_EQ(last_msg_.signed_messages[182], 75) - << "incorrect value for last_msg_.signed_messages[182], expected 75, is " - << last_msg_.signed_messages[182]; - EXPECT_EQ(last_msg_.signed_messages[183], 174) - << "incorrect value for last_msg_.signed_messages[183], expected 174, is " - << last_msg_.signed_messages[183]; - EXPECT_EQ(last_msg_.stream_counter, 1) - << "incorrect value for last_msg_.stream_counter, expected 1, is " - << last_msg_.stream_counter; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_a_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgEcdsaSignatureDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[0], greater.certificate_id[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[1], greater.certificate_id[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[2], greater.certificate_id[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[3], greater.certificate_id[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_signed_messages, greater.n_signed_messages); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.on_demand_counter, greater.on_demand_counter); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[0], greater.signature[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[1], greater.signature[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[2], greater.signature[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[3], greater.signature[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[4], greater.signature[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[5], greater.signature[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[6], greater.signature[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[7], greater.signature[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[8], greater.signature[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[9], greater.signature[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[10], greater.signature[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[11], greater.signature[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[12], greater.signature[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[13], greater.signature[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[14], greater.signature[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[15], greater.signature[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[16], greater.signature[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[17], greater.signature[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[18], greater.signature[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[19], greater.signature[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[20], greater.signature[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[21], greater.signature[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[22], greater.signature[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[23], greater.signature[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[24], greater.signature[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[25], greater.signature[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[26], greater.signature[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[27], greater.signature[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[28], greater.signature[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[29], greater.signature[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[30], greater.signature[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[31], greater.signature[31]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[32], greater.signature[32]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[33], greater.signature[33]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[34], greater.signature[34]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[35], greater.signature[35]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[36], greater.signature[36]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[37], greater.signature[37]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[38], greater.signature[38]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[39], greater.signature[39]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[40], greater.signature[40]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[41], greater.signature[41]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[42], greater.signature[42]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[43], greater.signature[43]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[44], greater.signature[44]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[45], greater.signature[45]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[46], greater.signature[46]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[47], greater.signature[47]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[48], greater.signature[48]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[49], greater.signature[49]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[50], greater.signature[50]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[51], greater.signature[51]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[52], greater.signature[52]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[53], greater.signature[53]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[54], greater.signature[54]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[55], greater.signature[55]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[56], greater.signature[56]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[57], greater.signature[57]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[58], greater.signature[58]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[59], greater.signature[59]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[60], greater.signature[60]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[61], greater.signature[61]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[62], greater.signature[62]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[63], greater.signature[63]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[0], greater.signed_messages[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[1], greater.signed_messages[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[2], greater.signed_messages[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[3], greater.signed_messages[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[4], greater.signed_messages[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[5], greater.signed_messages[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[6], greater.signed_messages[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[7], greater.signed_messages[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[8], greater.signed_messages[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[9], greater.signed_messages[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[10], + greater.signed_messages[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[11], + greater.signed_messages[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[12], + greater.signed_messages[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[13], + greater.signed_messages[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[14], + greater.signed_messages[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[15], + greater.signed_messages[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[16], + greater.signed_messages[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[17], + greater.signed_messages[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[18], + greater.signed_messages[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[19], + greater.signed_messages[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[20], + greater.signed_messages[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[21], + greater.signed_messages[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[22], + greater.signed_messages[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[23], + greater.signed_messages[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[24], + greater.signed_messages[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[25], + greater.signed_messages[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[26], + greater.signed_messages[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[27], + greater.signed_messages[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[28], + greater.signed_messages[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[29], + greater.signed_messages[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[30], + greater.signed_messages[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[31], + greater.signed_messages[31]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[32], + greater.signed_messages[32]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[33], + greater.signed_messages[33]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[34], + greater.signed_messages[34]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[35], + greater.signed_messages[35]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[36], + greater.signed_messages[36]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[37], + greater.signed_messages[37]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[38], + greater.signed_messages[38]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[39], + greater.signed_messages[39]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[40], + greater.signed_messages[40]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[41], + greater.signed_messages[41]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[42], + greater.signed_messages[42]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[43], + greater.signed_messages[43]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[44], + greater.signed_messages[44]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[45], + greater.signed_messages[45]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[46], + greater.signed_messages[46]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[47], + greater.signed_messages[47]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[48], + greater.signed_messages[48]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[49], + greater.signed_messages[49]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[50], + greater.signed_messages[50]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[51], + greater.signed_messages[51]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[52], + greater.signed_messages[52]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[53], + greater.signed_messages[53]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[54], + greater.signed_messages[54]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[55], + greater.signed_messages[55]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[56], + greater.signed_messages[56]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[57], + greater.signed_messages[57]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[58], + greater.signed_messages[58]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[59], + greater.signed_messages[59]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[60], + greater.signed_messages[60]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[61], + greater.signed_messages[61]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[62], + greater.signed_messages[62]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[63], + greater.signed_messages[63]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[64], + greater.signed_messages[64]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[65], + greater.signed_messages[65]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[66], + greater.signed_messages[66]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[67], + greater.signed_messages[67]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[68], + greater.signed_messages[68]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[69], + greater.signed_messages[69]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[70], + greater.signed_messages[70]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[71], + greater.signed_messages[71]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[72], + greater.signed_messages[72]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[73], + greater.signed_messages[73]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[74], + greater.signed_messages[74]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[75], + greater.signed_messages[75]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[76], + greater.signed_messages[76]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[77], + greater.signed_messages[77]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[78], + greater.signed_messages[78]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[79], + greater.signed_messages[79]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[80], + greater.signed_messages[80]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[81], + greater.signed_messages[81]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[82], + greater.signed_messages[82]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[83], + greater.signed_messages[83]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[84], + greater.signed_messages[84]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[85], + greater.signed_messages[85]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[86], + greater.signed_messages[86]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[87], + greater.signed_messages[87]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[88], + greater.signed_messages[88]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[89], + greater.signed_messages[89]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[90], + greater.signed_messages[90]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[91], + greater.signed_messages[91]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[92], + greater.signed_messages[92]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[93], + greater.signed_messages[93]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[94], + greater.signed_messages[94]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[95], + greater.signed_messages[95]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[96], + greater.signed_messages[96]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[97], + greater.signed_messages[97]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[98], + greater.signed_messages[98]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[99], + greater.signed_messages[99]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[100], + greater.signed_messages[100]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[101], + greater.signed_messages[101]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[102], + greater.signed_messages[102]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[103], + greater.signed_messages[103]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[104], + greater.signed_messages[104]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[105], + greater.signed_messages[105]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[106], + greater.signed_messages[106]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[107], + greater.signed_messages[107]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[108], + greater.signed_messages[108]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[109], + greater.signed_messages[109]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[110], + greater.signed_messages[110]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[111], + greater.signed_messages[111]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[112], + greater.signed_messages[112]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[113], + greater.signed_messages[113]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[114], + greater.signed_messages[114]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[115], + greater.signed_messages[115]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[116], + greater.signed_messages[116]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[117], + greater.signed_messages[117]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[118], + greater.signed_messages[118]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[119], + greater.signed_messages[119]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[120], + greater.signed_messages[120]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[121], + greater.signed_messages[121]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[122], + greater.signed_messages[122]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[123], + greater.signed_messages[123]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[124], + greater.signed_messages[124]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[125], + greater.signed_messages[125]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[126], + greater.signed_messages[126]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[127], + greater.signed_messages[127]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[128], + greater.signed_messages[128]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[129], + greater.signed_messages[129]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[130], + greater.signed_messages[130]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[131], + greater.signed_messages[131]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[132], + greater.signed_messages[132]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[133], + greater.signed_messages[133]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[134], + greater.signed_messages[134]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[135], + greater.signed_messages[135]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[136], + greater.signed_messages[136]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[137], + greater.signed_messages[137]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[138], + greater.signed_messages[138]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[139], + greater.signed_messages[139]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[140], + greater.signed_messages[140]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[141], + greater.signed_messages[141]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[142], + greater.signed_messages[142]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[143], + greater.signed_messages[143]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[144], + greater.signed_messages[144]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[145], + greater.signed_messages[145]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[146], + greater.signed_messages[146]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[147], + greater.signed_messages[147]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[148], + greater.signed_messages[148]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[149], + greater.signed_messages[149]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[150], + greater.signed_messages[150]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[151], + greater.signed_messages[151]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[152], + greater.signed_messages[152]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[153], + greater.signed_messages[153]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[154], + greater.signed_messages[154]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[155], + greater.signed_messages[155]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[156], + greater.signed_messages[156]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[157], + greater.signed_messages[157]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[158], + greater.signed_messages[158]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[159], + greater.signed_messages[159]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[160], + greater.signed_messages[160]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[161], + greater.signed_messages[161]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[162], + greater.signed_messages[162]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[163], + greater.signed_messages[163]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[164], + greater.signed_messages[164]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[165], + greater.signed_messages[165]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[166], + greater.signed_messages[166]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[167], + greater.signed_messages[167]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[168], + greater.signed_messages[168]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[169], + greater.signed_messages[169]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[170], + greater.signed_messages[170]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[171], + greater.signed_messages[171]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[172], + greater.signed_messages[172]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[173], + greater.signed_messages[173]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[174], + greater.signed_messages[174]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[175], + greater.signed_messages[175]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[176], + greater.signed_messages[176]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[177], + greater.signed_messages[177]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[178], + greater.signed_messages[178]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[179], + greater.signed_messages[179]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[180], + greater.signed_messages[180]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[181], + greater.signed_messages[181]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[182], + greater.signed_messages[182]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[183], + greater.signed_messages[183]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.stream_counter, greater.stream_counter); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEcdsaSignatureDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ECDSA_SIGNATURE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ecdsa_signature_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ecdsa_signature_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ecdsa_signature_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ecdsa_signature_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[255]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 255); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 255), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 255); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEcdsaSignatureDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEcdsaSignatureDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepB.cc b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepB.cc index 0c90a45514..604499b1f6 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepB.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEcdsaSignatureDepB.cc @@ -16,66 +16,440 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEcdsaSignatureDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEcdsaSignatureDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0() { + assign(test_msg_.certificate_id[0], 1); + + assign(test_msg_.certificate_id[1], 2); + + assign(test_msg_.certificate_id[2], 3); + + assign(test_msg_.certificate_id[3], 4); + assign(test_msg_.flags, 0); + assign(test_msg_.n_signature_bytes, 72); + assign(test_msg_.n_signed_messages, 3); + assign(test_msg_.on_demand_counter, 2); + + assign(test_msg_.signature[0], 0); + + assign(test_msg_.signature[1], 1); + + assign(test_msg_.signature[2], 2); + + assign(test_msg_.signature[3], 3); + + assign(test_msg_.signature[4], 4); + + assign(test_msg_.signature[5], 5); + + assign(test_msg_.signature[6], 6); + + assign(test_msg_.signature[7], 7); + + assign(test_msg_.signature[8], 8); + + assign(test_msg_.signature[9], 9); + + assign(test_msg_.signature[10], 10); + + assign(test_msg_.signature[11], 11); + + assign(test_msg_.signature[12], 12); + + assign(test_msg_.signature[13], 13); + + assign(test_msg_.signature[14], 14); + + assign(test_msg_.signature[15], 15); + + assign(test_msg_.signature[16], 16); + + assign(test_msg_.signature[17], 17); + + assign(test_msg_.signature[18], 18); + + assign(test_msg_.signature[19], 19); + + assign(test_msg_.signature[20], 20); + + assign(test_msg_.signature[21], 21); + + assign(test_msg_.signature[22], 22); + + assign(test_msg_.signature[23], 23); + + assign(test_msg_.signature[24], 24); + + assign(test_msg_.signature[25], 25); + + assign(test_msg_.signature[26], 26); + + assign(test_msg_.signature[27], 27); + + assign(test_msg_.signature[28], 28); + + assign(test_msg_.signature[29], 29); + + assign(test_msg_.signature[30], 30); + + assign(test_msg_.signature[31], 31); + + assign(test_msg_.signature[32], 32); + + assign(test_msg_.signature[33], 33); + + assign(test_msg_.signature[34], 34); + + assign(test_msg_.signature[35], 35); + + assign(test_msg_.signature[36], 36); + + assign(test_msg_.signature[37], 37); + + assign(test_msg_.signature[38], 38); + + assign(test_msg_.signature[39], 39); + + assign(test_msg_.signature[40], 40); + + assign(test_msg_.signature[41], 41); + + assign(test_msg_.signature[42], 42); + + assign(test_msg_.signature[43], 43); + + assign(test_msg_.signature[44], 44); + + assign(test_msg_.signature[45], 45); + + assign(test_msg_.signature[46], 46); + + assign(test_msg_.signature[47], 47); + + assign(test_msg_.signature[48], 48); + + assign(test_msg_.signature[49], 49); + + assign(test_msg_.signature[50], 50); + + assign(test_msg_.signature[51], 51); + + assign(test_msg_.signature[52], 52); + + assign(test_msg_.signature[53], 53); + + assign(test_msg_.signature[54], 54); + + assign(test_msg_.signature[55], 55); + + assign(test_msg_.signature[56], 56); + + assign(test_msg_.signature[57], 57); + + assign(test_msg_.signature[58], 58); + + assign(test_msg_.signature[59], 59); + + assign(test_msg_.signature[60], 60); + + assign(test_msg_.signature[61], 61); + + assign(test_msg_.signature[62], 62); + + assign(test_msg_.signature[63], 63); + + assign(test_msg_.signature[64], 64); + + assign(test_msg_.signature[65], 65); + + assign(test_msg_.signature[66], 66); + + assign(test_msg_.signature[67], 67); + + assign(test_msg_.signature[68], 68); + + assign(test_msg_.signature[69], 69); + + assign(test_msg_.signature[70], 70); + + assign(test_msg_.signature[71], 71); + + assign(test_msg_.signed_messages[0], 10); + + assign(test_msg_.signed_messages[1], 21); + + assign(test_msg_.signed_messages[2], 23); + assign(test_msg_.stream_counter, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ecdsa_signature_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEcdsaSignatureDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ecdsa_signature_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEcdsaSignatureDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ecdsa_signature_dep_b, + sizeof(msg->ecdsa_signature_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ecdsa_signature_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ecdsa_signature_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEcdsaSignatureDepB); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x9FFE; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 83; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ecdsa_signature_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ecdsa_signature_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ecdsa_signature_dep_b_t &lesser, + const sbp_msg_ecdsa_signature_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ecdsa_signature_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ecdsa_signature_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaSignatureDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEcdsaSignatureDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEcdsaSignatureDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEcdsaSignatureDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_signing_MsgEcdsaSignatureDepB0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ecdsa_signature_dep_b_t test_msg_{}; + uint8_t encoded_frame_[83 + 8] = { 85, 7, 12, 66, 0, 83, 0, 1, 2, 1, 2, 3, 4, 72, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -83,434 +457,908 @@ TEST_F(Test_auto_check_sbp_signing_MsgEcdsaSignatureDepB0, Test) { 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 10, 21, 23, 254, 159, }; + uint8_t encoded_payload_[83] = { + 0, 1, 2, 1, 2, 3, 4, 72, 0, 1, 2, 3, 4, 5, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 10, 21, 23, + }; +}; + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgEcdsaSignatureDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEcdsaSignatureDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + + for (uint8_t i = 0; i < 83; i++) { + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgEcdsaSignatureDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ecdsa_signature_dep_b_t t{}; + return sbp_msg_ecdsa_signature_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ecdsa_signature_dep_b_t t{}; + t.n_signed_messages = 1; + return sbp_msg_ecdsa_signature_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - sbp_msg_ecdsa_signature_dep_b_t test_msg{}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.certificate_id[0] = 1; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.certificate_id[1] = 2; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.certificate_id[2] = 3; + EXPECT_EQ(sbp_msg_ecdsa_signature_dep_b_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.certificate_id[3] = 4; - test_msg.flags = 0; - test_msg.n_signature_bytes = 72; - test_msg.n_signed_messages = 3; - test_msg.on_demand_counter = 2; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature[0] = 0; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature[1] = 1; + EXPECT_EQ(sbp_message_send(&state, SbpMsgEcdsaSignatureDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.signature[2] = 2; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, Comparison) { + auto info = get_test_msg_info(); - test_msg.signature[3] = 3; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[0], greater.certificate_id[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[4] = 4; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[1], greater.certificate_id[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[5] = 5; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[2], greater.certificate_id[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[6] = 6; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_id[3], greater.certificate_id[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_signature_bytes, greater.n_signature_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_signed_messages, greater.n_signed_messages); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.on_demand_counter, greater.on_demand_counter); + comparison_tests(lesser, greater); + } - test_msg.signature[7] = 7; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[0], greater.signature[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[8] = 8; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[1], greater.signature[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[9] = 9; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[2], greater.signature[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[10] = 10; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[3], greater.signature[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[11] = 11; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[4], greater.signature[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[12] = 12; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[5], greater.signature[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[13] = 13; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[6], greater.signature[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[7], greater.signature[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[8], greater.signature[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[9], greater.signature[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[10], greater.signature[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[11], greater.signature[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[12], greater.signature[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[14] = 14; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[13], greater.signature[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[15] = 15; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[14], greater.signature[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[16] = 16; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[15], greater.signature[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[16], greater.signature[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[17], greater.signature[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[18], greater.signature[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[19], greater.signature[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[20], greater.signature[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[21], greater.signature[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[22], greater.signature[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[23], greater.signature[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[24], greater.signature[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[25], greater.signature[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[26], greater.signature[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[27], greater.signature[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[28], greater.signature[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[29], greater.signature[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[30], greater.signature[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[31], greater.signature[31]); + comparison_tests(lesser, greater); + } - test_msg.signature[17] = 17; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[32], greater.signature[32]); + comparison_tests(lesser, greater); + } - test_msg.signature[18] = 18; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[33], greater.signature[33]); + comparison_tests(lesser, greater); + } - test_msg.signature[19] = 19; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[34], greater.signature[34]); + comparison_tests(lesser, greater); + } - test_msg.signature[20] = 20; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[35], greater.signature[35]); + comparison_tests(lesser, greater); + } - test_msg.signature[21] = 21; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[36], greater.signature[36]); + comparison_tests(lesser, greater); + } - test_msg.signature[22] = 22; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[37], greater.signature[37]); + comparison_tests(lesser, greater); + } - test_msg.signature[23] = 23; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[38], greater.signature[38]); + comparison_tests(lesser, greater); + } - test_msg.signature[24] = 24; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[39], greater.signature[39]); + comparison_tests(lesser, greater); + } - test_msg.signature[25] = 25; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[40], greater.signature[40]); + comparison_tests(lesser, greater); + } - test_msg.signature[26] = 26; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[41], greater.signature[41]); + comparison_tests(lesser, greater); + } - test_msg.signature[27] = 27; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[42], greater.signature[42]); + comparison_tests(lesser, greater); + } - test_msg.signature[28] = 28; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[43], greater.signature[43]); + comparison_tests(lesser, greater); + } - test_msg.signature[29] = 29; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[44], greater.signature[44]); + comparison_tests(lesser, greater); + } - test_msg.signature[30] = 30; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[45], greater.signature[45]); + comparison_tests(lesser, greater); + } - test_msg.signature[31] = 31; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[46], greater.signature[46]); + comparison_tests(lesser, greater); + } - test_msg.signature[32] = 32; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[47], greater.signature[47]); + comparison_tests(lesser, greater); + } - test_msg.signature[33] = 33; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[48], greater.signature[48]); + comparison_tests(lesser, greater); + } - test_msg.signature[34] = 34; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[49], greater.signature[49]); + comparison_tests(lesser, greater); + } - test_msg.signature[35] = 35; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[50], greater.signature[50]); + comparison_tests(lesser, greater); + } - test_msg.signature[36] = 36; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[51], greater.signature[51]); + comparison_tests(lesser, greater); + } - test_msg.signature[37] = 37; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[52], greater.signature[52]); + comparison_tests(lesser, greater); + } - test_msg.signature[38] = 38; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[53], greater.signature[53]); + comparison_tests(lesser, greater); + } - test_msg.signature[39] = 39; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[54], greater.signature[54]); + comparison_tests(lesser, greater); + } - test_msg.signature[40] = 40; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[55], greater.signature[55]); + comparison_tests(lesser, greater); + } - test_msg.signature[41] = 41; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[56], greater.signature[56]); + comparison_tests(lesser, greater); + } - test_msg.signature[42] = 42; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[57], greater.signature[57]); + comparison_tests(lesser, greater); + } - test_msg.signature[43] = 43; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[58], greater.signature[58]); + comparison_tests(lesser, greater); + } - test_msg.signature[44] = 44; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[59], greater.signature[59]); + comparison_tests(lesser, greater); + } - test_msg.signature[45] = 45; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[60], greater.signature[60]); + comparison_tests(lesser, greater); + } - test_msg.signature[46] = 46; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[61], greater.signature[61]); + comparison_tests(lesser, greater); + } - test_msg.signature[47] = 47; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[62], greater.signature[62]); + comparison_tests(lesser, greater); + } - test_msg.signature[48] = 48; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[63], greater.signature[63]); + comparison_tests(lesser, greater); + } - test_msg.signature[49] = 49; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[64], greater.signature[64]); + comparison_tests(lesser, greater); + } - test_msg.signature[50] = 50; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[65], greater.signature[65]); + comparison_tests(lesser, greater); + } - test_msg.signature[51] = 51; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[66], greater.signature[66]); + comparison_tests(lesser, greater); + } - test_msg.signature[52] = 52; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[67], greater.signature[67]); + comparison_tests(lesser, greater); + } - test_msg.signature[53] = 53; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[68], greater.signature[68]); + comparison_tests(lesser, greater); + } - test_msg.signature[54] = 54; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[69], greater.signature[69]); + comparison_tests(lesser, greater); + } - test_msg.signature[55] = 55; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[70], greater.signature[70]); + comparison_tests(lesser, greater); + } - test_msg.signature[56] = 56; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[71], greater.signature[71]); + comparison_tests(lesser, greater); + } - test_msg.signature[57] = 57; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[0], greater.signed_messages[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[58] = 58; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[1], greater.signed_messages[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[59] = 59; + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[2], greater.signed_messages[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ecdsa_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ecdsa_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.stream_counter, greater.stream_counter); + comparison_tests(lesser, greater); + } +} - test_msg.signature[60] = 60; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEcdsaSignatureDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ECDSA_SIGNATURE_DEP_B"); +} - test_msg.signature[61] = 61; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature[62] = 62; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.signature[63] = 63; + const sbp_msg_ecdsa_signature_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ecdsa_signature_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); - test_msg.signature[64] = 64; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.signature[65] = 65; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signature[66] = 66; + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ecdsa_signature_dep_b, info.test_msg); - test_msg.signature[67] = 67; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ecdsa_signature_dep_b, info.test_msg); +} - test_msg.signature[68] = 68; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.signature[69] = 69; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signature[70] = 70; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signature[71] = 71; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.signed_messages[0] = 10; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[83]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 83); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 83), 0); +} - test_msg.signed_messages[1] = 21; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ecdsa_signature_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 83); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signed_messages[2] = 23; - test_msg.stream_counter = 1; +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.certificate_id[0], 1) - << "incorrect value for last_msg_.certificate_id[0], expected 1, is " - << last_msg_.certificate_id[0]; - EXPECT_EQ(last_msg_.certificate_id[1], 2) - << "incorrect value for last_msg_.certificate_id[1], expected 2, is " - << last_msg_.certificate_id[1]; - EXPECT_EQ(last_msg_.certificate_id[2], 3) - << "incorrect value for last_msg_.certificate_id[2], expected 3, is " - << last_msg_.certificate_id[2]; - EXPECT_EQ(last_msg_.certificate_id[3], 4) - << "incorrect value for last_msg_.certificate_id[3], expected 4, is " - << last_msg_.certificate_id[3]; - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_signature_bytes, 72) - << "incorrect value for last_msg_.n_signature_bytes, expected 72, is " - << last_msg_.n_signature_bytes; - EXPECT_EQ(last_msg_.n_signed_messages, 3) - << "incorrect value for last_msg_.n_signed_messages, expected 3, is " - << last_msg_.n_signed_messages; - EXPECT_EQ(last_msg_.on_demand_counter, 2) - << "incorrect value for last_msg_.on_demand_counter, expected 2, is " - << last_msg_.on_demand_counter; - EXPECT_EQ(last_msg_.signature[0], 0) - << "incorrect value for last_msg_.signature[0], expected 0, is " - << last_msg_.signature[0]; - EXPECT_EQ(last_msg_.signature[1], 1) - << "incorrect value for last_msg_.signature[1], expected 1, is " - << last_msg_.signature[1]; - EXPECT_EQ(last_msg_.signature[2], 2) - << "incorrect value for last_msg_.signature[2], expected 2, is " - << last_msg_.signature[2]; - EXPECT_EQ(last_msg_.signature[3], 3) - << "incorrect value for last_msg_.signature[3], expected 3, is " - << last_msg_.signature[3]; - EXPECT_EQ(last_msg_.signature[4], 4) - << "incorrect value for last_msg_.signature[4], expected 4, is " - << last_msg_.signature[4]; - EXPECT_EQ(last_msg_.signature[5], 5) - << "incorrect value for last_msg_.signature[5], expected 5, is " - << last_msg_.signature[5]; - EXPECT_EQ(last_msg_.signature[6], 6) - << "incorrect value for last_msg_.signature[6], expected 6, is " - << last_msg_.signature[6]; - EXPECT_EQ(last_msg_.signature[7], 7) - << "incorrect value for last_msg_.signature[7], expected 7, is " - << last_msg_.signature[7]; - EXPECT_EQ(last_msg_.signature[8], 8) - << "incorrect value for last_msg_.signature[8], expected 8, is " - << last_msg_.signature[8]; - EXPECT_EQ(last_msg_.signature[9], 9) - << "incorrect value for last_msg_.signature[9], expected 9, is " - << last_msg_.signature[9]; - EXPECT_EQ(last_msg_.signature[10], 10) - << "incorrect value for last_msg_.signature[10], expected 10, is " - << last_msg_.signature[10]; - EXPECT_EQ(last_msg_.signature[11], 11) - << "incorrect value for last_msg_.signature[11], expected 11, is " - << last_msg_.signature[11]; - EXPECT_EQ(last_msg_.signature[12], 12) - << "incorrect value for last_msg_.signature[12], expected 12, is " - << last_msg_.signature[12]; - EXPECT_EQ(last_msg_.signature[13], 13) - << "incorrect value for last_msg_.signature[13], expected 13, is " - << last_msg_.signature[13]; - EXPECT_EQ(last_msg_.signature[14], 14) - << "incorrect value for last_msg_.signature[14], expected 14, is " - << last_msg_.signature[14]; - EXPECT_EQ(last_msg_.signature[15], 15) - << "incorrect value for last_msg_.signature[15], expected 15, is " - << last_msg_.signature[15]; - EXPECT_EQ(last_msg_.signature[16], 16) - << "incorrect value for last_msg_.signature[16], expected 16, is " - << last_msg_.signature[16]; - EXPECT_EQ(last_msg_.signature[17], 17) - << "incorrect value for last_msg_.signature[17], expected 17, is " - << last_msg_.signature[17]; - EXPECT_EQ(last_msg_.signature[18], 18) - << "incorrect value for last_msg_.signature[18], expected 18, is " - << last_msg_.signature[18]; - EXPECT_EQ(last_msg_.signature[19], 19) - << "incorrect value for last_msg_.signature[19], expected 19, is " - << last_msg_.signature[19]; - EXPECT_EQ(last_msg_.signature[20], 20) - << "incorrect value for last_msg_.signature[20], expected 20, is " - << last_msg_.signature[20]; - EXPECT_EQ(last_msg_.signature[21], 21) - << "incorrect value for last_msg_.signature[21], expected 21, is " - << last_msg_.signature[21]; - EXPECT_EQ(last_msg_.signature[22], 22) - << "incorrect value for last_msg_.signature[22], expected 22, is " - << last_msg_.signature[22]; - EXPECT_EQ(last_msg_.signature[23], 23) - << "incorrect value for last_msg_.signature[23], expected 23, is " - << last_msg_.signature[23]; - EXPECT_EQ(last_msg_.signature[24], 24) - << "incorrect value for last_msg_.signature[24], expected 24, is " - << last_msg_.signature[24]; - EXPECT_EQ(last_msg_.signature[25], 25) - << "incorrect value for last_msg_.signature[25], expected 25, is " - << last_msg_.signature[25]; - EXPECT_EQ(last_msg_.signature[26], 26) - << "incorrect value for last_msg_.signature[26], expected 26, is " - << last_msg_.signature[26]; - EXPECT_EQ(last_msg_.signature[27], 27) - << "incorrect value for last_msg_.signature[27], expected 27, is " - << last_msg_.signature[27]; - EXPECT_EQ(last_msg_.signature[28], 28) - << "incorrect value for last_msg_.signature[28], expected 28, is " - << last_msg_.signature[28]; - EXPECT_EQ(last_msg_.signature[29], 29) - << "incorrect value for last_msg_.signature[29], expected 29, is " - << last_msg_.signature[29]; - EXPECT_EQ(last_msg_.signature[30], 30) - << "incorrect value for last_msg_.signature[30], expected 30, is " - << last_msg_.signature[30]; - EXPECT_EQ(last_msg_.signature[31], 31) - << "incorrect value for last_msg_.signature[31], expected 31, is " - << last_msg_.signature[31]; - EXPECT_EQ(last_msg_.signature[32], 32) - << "incorrect value for last_msg_.signature[32], expected 32, is " - << last_msg_.signature[32]; - EXPECT_EQ(last_msg_.signature[33], 33) - << "incorrect value for last_msg_.signature[33], expected 33, is " - << last_msg_.signature[33]; - EXPECT_EQ(last_msg_.signature[34], 34) - << "incorrect value for last_msg_.signature[34], expected 34, is " - << last_msg_.signature[34]; - EXPECT_EQ(last_msg_.signature[35], 35) - << "incorrect value for last_msg_.signature[35], expected 35, is " - << last_msg_.signature[35]; - EXPECT_EQ(last_msg_.signature[36], 36) - << "incorrect value for last_msg_.signature[36], expected 36, is " - << last_msg_.signature[36]; - EXPECT_EQ(last_msg_.signature[37], 37) - << "incorrect value for last_msg_.signature[37], expected 37, is " - << last_msg_.signature[37]; - EXPECT_EQ(last_msg_.signature[38], 38) - << "incorrect value for last_msg_.signature[38], expected 38, is " - << last_msg_.signature[38]; - EXPECT_EQ(last_msg_.signature[39], 39) - << "incorrect value for last_msg_.signature[39], expected 39, is " - << last_msg_.signature[39]; - EXPECT_EQ(last_msg_.signature[40], 40) - << "incorrect value for last_msg_.signature[40], expected 40, is " - << last_msg_.signature[40]; - EXPECT_EQ(last_msg_.signature[41], 41) - << "incorrect value for last_msg_.signature[41], expected 41, is " - << last_msg_.signature[41]; - EXPECT_EQ(last_msg_.signature[42], 42) - << "incorrect value for last_msg_.signature[42], expected 42, is " - << last_msg_.signature[42]; - EXPECT_EQ(last_msg_.signature[43], 43) - << "incorrect value for last_msg_.signature[43], expected 43, is " - << last_msg_.signature[43]; - EXPECT_EQ(last_msg_.signature[44], 44) - << "incorrect value for last_msg_.signature[44], expected 44, is " - << last_msg_.signature[44]; - EXPECT_EQ(last_msg_.signature[45], 45) - << "incorrect value for last_msg_.signature[45], expected 45, is " - << last_msg_.signature[45]; - EXPECT_EQ(last_msg_.signature[46], 46) - << "incorrect value for last_msg_.signature[46], expected 46, is " - << last_msg_.signature[46]; - EXPECT_EQ(last_msg_.signature[47], 47) - << "incorrect value for last_msg_.signature[47], expected 47, is " - << last_msg_.signature[47]; - EXPECT_EQ(last_msg_.signature[48], 48) - << "incorrect value for last_msg_.signature[48], expected 48, is " - << last_msg_.signature[48]; - EXPECT_EQ(last_msg_.signature[49], 49) - << "incorrect value for last_msg_.signature[49], expected 49, is " - << last_msg_.signature[49]; - EXPECT_EQ(last_msg_.signature[50], 50) - << "incorrect value for last_msg_.signature[50], expected 50, is " - << last_msg_.signature[50]; - EXPECT_EQ(last_msg_.signature[51], 51) - << "incorrect value for last_msg_.signature[51], expected 51, is " - << last_msg_.signature[51]; - EXPECT_EQ(last_msg_.signature[52], 52) - << "incorrect value for last_msg_.signature[52], expected 52, is " - << last_msg_.signature[52]; - EXPECT_EQ(last_msg_.signature[53], 53) - << "incorrect value for last_msg_.signature[53], expected 53, is " - << last_msg_.signature[53]; - EXPECT_EQ(last_msg_.signature[54], 54) - << "incorrect value for last_msg_.signature[54], expected 54, is " - << last_msg_.signature[54]; - EXPECT_EQ(last_msg_.signature[55], 55) - << "incorrect value for last_msg_.signature[55], expected 55, is " - << last_msg_.signature[55]; - EXPECT_EQ(last_msg_.signature[56], 56) - << "incorrect value for last_msg_.signature[56], expected 56, is " - << last_msg_.signature[56]; - EXPECT_EQ(last_msg_.signature[57], 57) - << "incorrect value for last_msg_.signature[57], expected 57, is " - << last_msg_.signature[57]; - EXPECT_EQ(last_msg_.signature[58], 58) - << "incorrect value for last_msg_.signature[58], expected 58, is " - << last_msg_.signature[58]; - EXPECT_EQ(last_msg_.signature[59], 59) - << "incorrect value for last_msg_.signature[59], expected 59, is " - << last_msg_.signature[59]; - EXPECT_EQ(last_msg_.signature[60], 60) - << "incorrect value for last_msg_.signature[60], expected 60, is " - << last_msg_.signature[60]; - EXPECT_EQ(last_msg_.signature[61], 61) - << "incorrect value for last_msg_.signature[61], expected 61, is " - << last_msg_.signature[61]; - EXPECT_EQ(last_msg_.signature[62], 62) - << "incorrect value for last_msg_.signature[62], expected 62, is " - << last_msg_.signature[62]; - EXPECT_EQ(last_msg_.signature[63], 63) - << "incorrect value for last_msg_.signature[63], expected 63, is " - << last_msg_.signature[63]; - EXPECT_EQ(last_msg_.signature[64], 64) - << "incorrect value for last_msg_.signature[64], expected 64, is " - << last_msg_.signature[64]; - EXPECT_EQ(last_msg_.signature[65], 65) - << "incorrect value for last_msg_.signature[65], expected 65, is " - << last_msg_.signature[65]; - EXPECT_EQ(last_msg_.signature[66], 66) - << "incorrect value for last_msg_.signature[66], expected 66, is " - << last_msg_.signature[66]; - EXPECT_EQ(last_msg_.signature[67], 67) - << "incorrect value for last_msg_.signature[67], expected 67, is " - << last_msg_.signature[67]; - EXPECT_EQ(last_msg_.signature[68], 68) - << "incorrect value for last_msg_.signature[68], expected 68, is " - << last_msg_.signature[68]; - EXPECT_EQ(last_msg_.signature[69], 69) - << "incorrect value for last_msg_.signature[69], expected 69, is " - << last_msg_.signature[69]; - EXPECT_EQ(last_msg_.signature[70], 70) - << "incorrect value for last_msg_.signature[70], expected 70, is " - << last_msg_.signature[70]; - EXPECT_EQ(last_msg_.signature[71], 71) - << "incorrect value for last_msg_.signature[71], expected 71, is " - << last_msg_.signature[71]; - EXPECT_EQ(last_msg_.signed_messages[0], 10) - << "incorrect value for last_msg_.signed_messages[0], expected 10, is " - << last_msg_.signed_messages[0]; - EXPECT_EQ(last_msg_.signed_messages[1], 21) - << "incorrect value for last_msg_.signed_messages[1], expected 21, is " - << last_msg_.signed_messages[1]; - EXPECT_EQ(last_msg_.signed_messages[2], 23) - << "incorrect value for last_msg_.signed_messages[2], expected 23, is " - << last_msg_.signed_messages[2]; - EXPECT_EQ(last_msg_.stream_counter, 1) - << "incorrect value for last_msg_.stream_counter, expected 1, is " - << last_msg_.stream_counter; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEcdsaSignatureDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEcdsaSignatureDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEcdsaSignatureDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEd25519CertificateDep.cc b/c/test/cpp/auto_check_sbp_signing_MsgEd25519CertificateDep.cc index 66c25d5718..282cb96871 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEd25519CertificateDep.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEd25519CertificateDep.cc @@ -16,66 +16,491 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEd25519CertificateDep0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEd25519CertificateDep0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEd25519CertificateDep0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgEd25519CertificateDep0() { + assign(test_msg_.certificate_bytes[0], 0); + + assign(test_msg_.certificate_bytes[1], 3); + + assign(test_msg_.certificate_bytes[2], 6); + + assign(test_msg_.certificate_bytes[3], 9); + + assign(test_msg_.certificate_bytes[4], 12); + + assign(test_msg_.certificate_bytes[5], 15); + + assign(test_msg_.certificate_bytes[6], 18); + + assign(test_msg_.certificate_bytes[7], 21); + + assign(test_msg_.certificate_bytes[8], 24); + + assign(test_msg_.certificate_bytes[9], 27); + + assign(test_msg_.certificate_bytes[10], 30); + + assign(test_msg_.certificate_bytes[11], 33); + + assign(test_msg_.certificate_bytes[12], 36); + + assign(test_msg_.certificate_bytes[13], 39); + + assign(test_msg_.certificate_bytes[14], 42); + + assign(test_msg_.certificate_bytes[15], 45); + + assign(test_msg_.certificate_bytes[16], 48); + + assign(test_msg_.certificate_bytes[17], 51); + + assign(test_msg_.certificate_bytes[18], 54); + + assign(test_msg_.certificate_bytes[19], 57); + + assign(test_msg_.certificate_bytes[20], 60); + + assign(test_msg_.certificate_bytes[21], 63); + + assign(test_msg_.certificate_bytes[22], 66); + + assign(test_msg_.certificate_bytes[23], 69); + + assign(test_msg_.certificate_bytes[24], 72); + + assign(test_msg_.certificate_bytes[25], 75); + + assign(test_msg_.certificate_bytes[26], 78); + + assign(test_msg_.certificate_bytes[27], 81); + + assign(test_msg_.certificate_bytes[28], 84); + + assign(test_msg_.certificate_bytes[29], 87); + + assign(test_msg_.certificate_bytes[30], 90); + + assign(test_msg_.certificate_bytes[31], 93); + + assign(test_msg_.certificate_bytes[32], 96); + + assign(test_msg_.certificate_bytes[33], 99); + + assign(test_msg_.certificate_bytes[34], 102); + + assign(test_msg_.certificate_bytes[35], 105); + + assign(test_msg_.certificate_bytes[36], 108); + + assign(test_msg_.certificate_bytes[37], 111); + + assign(test_msg_.certificate_bytes[38], 114); + + assign(test_msg_.certificate_bytes[39], 117); + + assign(test_msg_.certificate_bytes[40], 120); + + assign(test_msg_.certificate_bytes[41], 123); + + assign(test_msg_.certificate_bytes[42], 126); + + assign(test_msg_.certificate_bytes[43], 129); + + assign(test_msg_.certificate_bytes[44], 132); + + assign(test_msg_.certificate_bytes[45], 135); + + assign(test_msg_.certificate_bytes[46], 138); + + assign(test_msg_.certificate_bytes[47], 141); + + assign(test_msg_.certificate_bytes[48], 144); + + assign(test_msg_.certificate_bytes[49], 147); + + assign(test_msg_.certificate_bytes[50], 150); + + assign(test_msg_.certificate_bytes[51], 153); + + assign(test_msg_.certificate_bytes[52], 156); + + assign(test_msg_.certificate_bytes[53], 159); + + assign(test_msg_.certificate_bytes[54], 162); + + assign(test_msg_.certificate_bytes[55], 165); + + assign(test_msg_.certificate_bytes[56], 168); + + assign(test_msg_.certificate_bytes[57], 171); + + assign(test_msg_.certificate_bytes[58], 174); + + assign(test_msg_.certificate_bytes[59], 177); + + assign(test_msg_.certificate_bytes[60], 180); + + assign(test_msg_.certificate_bytes[61], 183); + + assign(test_msg_.certificate_bytes[62], 186); + + assign(test_msg_.certificate_bytes[63], 189); + + assign(test_msg_.certificate_bytes[64], 192); + + assign(test_msg_.certificate_bytes[65], 195); + + assign(test_msg_.certificate_bytes[66], 198); + + assign(test_msg_.certificate_bytes[67], 201); + + assign(test_msg_.certificate_bytes[68], 204); + + assign(test_msg_.certificate_bytes[69], 207); + + assign(test_msg_.certificate_bytes[70], 210); + + assign(test_msg_.certificate_bytes[71], 213); + + assign(test_msg_.certificate_bytes[72], 216); + + assign(test_msg_.certificate_bytes[73], 219); + + assign(test_msg_.certificate_bytes[74], 222); + + assign(test_msg_.certificate_bytes[75], 225); + + assign(test_msg_.certificate_bytes[76], 228); + + assign(test_msg_.certificate_bytes[77], 231); + + assign(test_msg_.certificate_bytes[78], 234); + + assign(test_msg_.certificate_bytes[79], 237); + + assign(test_msg_.certificate_bytes[80], 240); + + assign(test_msg_.certificate_bytes[81], 243); + + assign(test_msg_.certificate_bytes[82], 246); + + assign(test_msg_.certificate_bytes[83], 249); + + assign(test_msg_.certificate_bytes[84], 252); + + assign(test_msg_.fingerprint[0], 100); + + assign(test_msg_.fingerprint[1], 101); + + assign(test_msg_.fingerprint[2], 102); + + assign(test_msg_.fingerprint[3], 103); + + assign(test_msg_.fingerprint[4], 104); + + assign(test_msg_.fingerprint[5], 105); + + assign(test_msg_.fingerprint[6], 106); + + assign(test_msg_.fingerprint[7], 107); + + assign(test_msg_.fingerprint[8], 108); + + assign(test_msg_.fingerprint[9], 109); + + assign(test_msg_.fingerprint[10], 110); + + assign(test_msg_.fingerprint[11], 111); + + assign(test_msg_.fingerprint[12], 112); + + assign(test_msg_.fingerprint[13], 113); + + assign(test_msg_.fingerprint[14], 114); + + assign(test_msg_.fingerprint[15], 115); + + assign(test_msg_.fingerprint[16], 116); + + assign(test_msg_.fingerprint[17], 117); + + assign(test_msg_.fingerprint[18], 118); + + assign(test_msg_.fingerprint[19], 119); + assign(test_msg_.n_certificate_bytes, 85); + assign(test_msg_.n_msg, 16); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ed25519_certificate_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_certificate_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ed25519_certificate_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEd25519CertificateDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_certificate_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEd25519CertificateDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ed25519_certificate_dep, + sizeof(msg->ed25519_certificate_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ed25519_certificate_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ed25519_certificate_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEd25519CertificateDep); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x94DA; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 106; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ed25519_certificate_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ed25519_certificate_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ed25519_certificate_dep_t &lesser, + const sbp_msg_ed25519_certificate_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ed25519_certificate_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ed25519_certificate_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519CertificateDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519CertificateDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEd25519CertificateDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEd25519CertificateDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_signing_MsgEd25519CertificateDep0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ed25519_certificate_dep_t test_msg_{}; + uint8_t encoded_frame_[106 + 8] = { 85, 2, 12, 66, 0, 106, 16, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 0, 3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, @@ -85,603 +510,1169 @@ TEST_F(Test_auto_check_sbp_signing_MsgEd25519CertificateDep0, Test) { 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, 231, 234, 237, 240, 243, 246, 249, 252, 218, 148, }; + uint8_t encoded_payload_[106] = { + 16, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 113, 114, 115, 116, 117, 118, 119, 0, 3, 6, 9, 12, 15, 18, + 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, + 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99, 102, + 105, 108, 111, 114, 117, 120, 123, 126, 129, 132, 135, 138, 141, 144, + 147, 150, 153, 156, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, + 189, 192, 195, 198, 201, 204, 207, 210, 213, 216, 219, 222, 225, 228, + 231, 234, 237, 240, 243, 246, 249, 252, + }; +}; - sbp_msg_ed25519_certificate_dep_t test_msg{}; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_encoded_len(&info.test_msg), + info.payload_len); - test_msg.certificate_bytes[0] = 0; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEd25519CertificateDep, + &info.test_msg_wrapped), + info.payload_len); +} - test_msg.certificate_bytes[1] = 3; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[106]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 106); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 106), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEd25519CertificateDep, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 106); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 106), 0); +} - test_msg.certificate_bytes[2] = 6; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[106]; - test_msg.certificate_bytes[3] = 9; + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 106), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[106]; + + for (uint8_t i = 0; i < 106; i++) { + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.certificate_bytes[4] = 12; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_certificate_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 106); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgEd25519CertificateDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 106); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.certificate_bytes[5] = 15; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_certificate_dep_t msg{}; - test_msg.certificate_bytes[6] = 18; + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_certificate_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ed25519_certificate_dep_t t{}; + return sbp_msg_ed25519_certificate_dep_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ed25519_certificate_dep_t t{}; + t.n_certificate_bytes = 1; + return sbp_msg_ed25519_certificate_dep_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} - test_msg.certificate_bytes[7] = 21; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.certificate_bytes[8] = 24; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.certificate_bytes[9] = 27; + CHandler handler{&state}; - test_msg.certificate_bytes[10] = 30; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.certificate_bytes[11] = 33; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.certificate_bytes[12] = 36; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.certificate_bytes[13] = 39; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.certificate_bytes[14] = 42; + EXPECT_EQ(sbp_msg_ed25519_certificate_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.certificate_bytes[15] = 45; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgEd25519CertificateDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.certificate_bytes[16] = 48; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, Comparison) { + auto info = get_test_msg_info(); - test_msg.certificate_bytes[17] = 51; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[0], + greater.certificate_bytes[0]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[18] = 54; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[1], + greater.certificate_bytes[1]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[19] = 57; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[2], + greater.certificate_bytes[2]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[20] = 60; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[3], + greater.certificate_bytes[3]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[21] = 63; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[4], + greater.certificate_bytes[4]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[22] = 66; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[5], + greater.certificate_bytes[5]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[23] = 69; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[6], + greater.certificate_bytes[6]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[24] = 72; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[7], + greater.certificate_bytes[7]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[25] = 75; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[8], + greater.certificate_bytes[8]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[26] = 78; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[9], + greater.certificate_bytes[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[10], + greater.certificate_bytes[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[11], + greater.certificate_bytes[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[12], + greater.certificate_bytes[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[13], + greater.certificate_bytes[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[14], + greater.certificate_bytes[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[15], + greater.certificate_bytes[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[16], + greater.certificate_bytes[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[17], + greater.certificate_bytes[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[18], + greater.certificate_bytes[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[19], + greater.certificate_bytes[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[20], + greater.certificate_bytes[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[21], + greater.certificate_bytes[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[22], + greater.certificate_bytes[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[23], + greater.certificate_bytes[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[24], + greater.certificate_bytes[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[25], + greater.certificate_bytes[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[26], + greater.certificate_bytes[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[27], + greater.certificate_bytes[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[28], + greater.certificate_bytes[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[29], + greater.certificate_bytes[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[30], + greater.certificate_bytes[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[31], + greater.certificate_bytes[31]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[32], + greater.certificate_bytes[32]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[33], + greater.certificate_bytes[33]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[34], + greater.certificate_bytes[34]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[35], + greater.certificate_bytes[35]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[36], + greater.certificate_bytes[36]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[37], + greater.certificate_bytes[37]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[27] = 81; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[38], + greater.certificate_bytes[38]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[28] = 84; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[39], + greater.certificate_bytes[39]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[29] = 87; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[40], + greater.certificate_bytes[40]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[30] = 90; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[41], + greater.certificate_bytes[41]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[31] = 93; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[42], + greater.certificate_bytes[42]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[32] = 96; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[43], + greater.certificate_bytes[43]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[33] = 99; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[44], + greater.certificate_bytes[44]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[34] = 102; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[45], + greater.certificate_bytes[45]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[35] = 105; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[46], + greater.certificate_bytes[46]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[36] = 108; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[47], + greater.certificate_bytes[47]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[37] = 111; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[48], + greater.certificate_bytes[48]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[49], + greater.certificate_bytes[49]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[50], + greater.certificate_bytes[50]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[51], + greater.certificate_bytes[51]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[52], + greater.certificate_bytes[52]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[38] = 114; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[53], + greater.certificate_bytes[53]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[39] = 117; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[54], + greater.certificate_bytes[54]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[40] = 120; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[55], + greater.certificate_bytes[55]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[41] = 123; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[56], + greater.certificate_bytes[56]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[42] = 126; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[57], + greater.certificate_bytes[57]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[43] = 129; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[58], + greater.certificate_bytes[58]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[44] = 132; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[59], + greater.certificate_bytes[59]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[45] = 135; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[60], + greater.certificate_bytes[60]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[46] = 138; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[61], + greater.certificate_bytes[61]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[47] = 141; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[62], + greater.certificate_bytes[62]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[48] = 144; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[63], + greater.certificate_bytes[63]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[49] = 147; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[64], + greater.certificate_bytes[64]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[50] = 150; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[65], + greater.certificate_bytes[65]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[51] = 153; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[66], + greater.certificate_bytes[66]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[52] = 156; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[67], + greater.certificate_bytes[67]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[53] = 159; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[68], + greater.certificate_bytes[68]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[54] = 162; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[69], + greater.certificate_bytes[69]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[55] = 165; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[70], + greater.certificate_bytes[70]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[56] = 168; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[71], + greater.certificate_bytes[71]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[57] = 171; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[72], + greater.certificate_bytes[72]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[58] = 174; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[73], + greater.certificate_bytes[73]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[59] = 177; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[74], + greater.certificate_bytes[74]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[60] = 180; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[75], + greater.certificate_bytes[75]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[61] = 183; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[76], + greater.certificate_bytes[76]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[62] = 186; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[77], + greater.certificate_bytes[77]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[63] = 189; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[78], + greater.certificate_bytes[78]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[64] = 192; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[79], + greater.certificate_bytes[79]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[65] = 195; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[80], + greater.certificate_bytes[80]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[66] = 198; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[81], + greater.certificate_bytes[81]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[67] = 201; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[82], + greater.certificate_bytes[82]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[68] = 204; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[83], + greater.certificate_bytes[83]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[69] = 207; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.certificate_bytes[84], + greater.certificate_bytes[84]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[70] = 210; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[0], greater.fingerprint[0]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[71] = 213; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[1], greater.fingerprint[1]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[72] = 216; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[2], greater.fingerprint[2]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[73] = 219; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[3], greater.fingerprint[3]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[74] = 222; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[4], greater.fingerprint[4]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[75] = 225; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[5], greater.fingerprint[5]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[76] = 228; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[6], greater.fingerprint[6]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[77] = 231; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[7], greater.fingerprint[7]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[78] = 234; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[8], greater.fingerprint[8]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[79] = 237; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[9], greater.fingerprint[9]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[80] = 240; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[10], greater.fingerprint[10]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[81] = 243; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[11], greater.fingerprint[11]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[82] = 246; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[12], greater.fingerprint[12]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[83] = 249; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[13], greater.fingerprint[13]); + comparison_tests(lesser, greater); + } - test_msg.certificate_bytes[84] = 252; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[14], greater.fingerprint[14]); + comparison_tests(lesser, greater); + } - test_msg.fingerprint[0] = 100; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[15], greater.fingerprint[15]); + comparison_tests(lesser, greater); + } - test_msg.fingerprint[1] = 101; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[16], greater.fingerprint[16]); + comparison_tests(lesser, greater); + } - test_msg.fingerprint[2] = 102; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[17], greater.fingerprint[17]); + comparison_tests(lesser, greater); + } - test_msg.fingerprint[3] = 103; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[18], greater.fingerprint[18]); + comparison_tests(lesser, greater); + } - test_msg.fingerprint[4] = 104; + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[19], greater.fingerprint[19]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.n_certificate_bytes, + greater.n_certificate_bytes); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_certificate_dep_t lesser = info.test_msg; + sbp_msg_ed25519_certificate_dep_t greater = info.test_msg; + make_lesser_greater(lesser.n_msg, greater.n_msg); + comparison_tests(lesser, greater); + } +} - test_msg.fingerprint[5] = 105; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEd25519CertificateDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ED25519_CERTIFICATE_DEP"); +} - test_msg.fingerprint[6] = 106; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.fingerprint[7] = 107; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.fingerprint[8] = 108; + const sbp_msg_ed25519_certificate_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ed25519_certificate_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); - test_msg.fingerprint[9] = 109; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.fingerprint[10] = 110; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.fingerprint[11] = 111; + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ed25519_certificate_dep, info.test_msg); - test_msg.fingerprint[12] = 112; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ed25519_certificate_dep, info.test_msg); +} - test_msg.fingerprint[13] = 113; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.fingerprint[14] = 114; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[15] = 115; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.fingerprint[16] = 116; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.fingerprint[17] = 117; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[106]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 106); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 106), 0); +} - test_msg.fingerprint[18] = 118; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_certificate_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 106); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.fingerprint[19] = 119; - test_msg.n_certificate_bytes = 85; - test_msg.n_msg = 16; +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.certificate_bytes[0], 0) - << "incorrect value for last_msg_.certificate_bytes[0], expected 0, is " - << last_msg_.certificate_bytes[0]; - EXPECT_EQ(last_msg_.certificate_bytes[1], 3) - << "incorrect value for last_msg_.certificate_bytes[1], expected 3, is " - << last_msg_.certificate_bytes[1]; - EXPECT_EQ(last_msg_.certificate_bytes[2], 6) - << "incorrect value for last_msg_.certificate_bytes[2], expected 6, is " - << last_msg_.certificate_bytes[2]; - EXPECT_EQ(last_msg_.certificate_bytes[3], 9) - << "incorrect value for last_msg_.certificate_bytes[3], expected 9, is " - << last_msg_.certificate_bytes[3]; - EXPECT_EQ(last_msg_.certificate_bytes[4], 12) - << "incorrect value for last_msg_.certificate_bytes[4], expected 12, is " - << last_msg_.certificate_bytes[4]; - EXPECT_EQ(last_msg_.certificate_bytes[5], 15) - << "incorrect value for last_msg_.certificate_bytes[5], expected 15, is " - << last_msg_.certificate_bytes[5]; - EXPECT_EQ(last_msg_.certificate_bytes[6], 18) - << "incorrect value for last_msg_.certificate_bytes[6], expected 18, is " - << last_msg_.certificate_bytes[6]; - EXPECT_EQ(last_msg_.certificate_bytes[7], 21) - << "incorrect value for last_msg_.certificate_bytes[7], expected 21, is " - << last_msg_.certificate_bytes[7]; - EXPECT_EQ(last_msg_.certificate_bytes[8], 24) - << "incorrect value for last_msg_.certificate_bytes[8], expected 24, is " - << last_msg_.certificate_bytes[8]; - EXPECT_EQ(last_msg_.certificate_bytes[9], 27) - << "incorrect value for last_msg_.certificate_bytes[9], expected 27, is " - << last_msg_.certificate_bytes[9]; - EXPECT_EQ(last_msg_.certificate_bytes[10], 30) - << "incorrect value for last_msg_.certificate_bytes[10], expected 30, is " - << last_msg_.certificate_bytes[10]; - EXPECT_EQ(last_msg_.certificate_bytes[11], 33) - << "incorrect value for last_msg_.certificate_bytes[11], expected 33, is " - << last_msg_.certificate_bytes[11]; - EXPECT_EQ(last_msg_.certificate_bytes[12], 36) - << "incorrect value for last_msg_.certificate_bytes[12], expected 36, is " - << last_msg_.certificate_bytes[12]; - EXPECT_EQ(last_msg_.certificate_bytes[13], 39) - << "incorrect value for last_msg_.certificate_bytes[13], expected 39, is " - << last_msg_.certificate_bytes[13]; - EXPECT_EQ(last_msg_.certificate_bytes[14], 42) - << "incorrect value for last_msg_.certificate_bytes[14], expected 42, is " - << last_msg_.certificate_bytes[14]; - EXPECT_EQ(last_msg_.certificate_bytes[15], 45) - << "incorrect value for last_msg_.certificate_bytes[15], expected 45, is " - << last_msg_.certificate_bytes[15]; - EXPECT_EQ(last_msg_.certificate_bytes[16], 48) - << "incorrect value for last_msg_.certificate_bytes[16], expected 48, is " - << last_msg_.certificate_bytes[16]; - EXPECT_EQ(last_msg_.certificate_bytes[17], 51) - << "incorrect value for last_msg_.certificate_bytes[17], expected 51, is " - << last_msg_.certificate_bytes[17]; - EXPECT_EQ(last_msg_.certificate_bytes[18], 54) - << "incorrect value for last_msg_.certificate_bytes[18], expected 54, is " - << last_msg_.certificate_bytes[18]; - EXPECT_EQ(last_msg_.certificate_bytes[19], 57) - << "incorrect value for last_msg_.certificate_bytes[19], expected 57, is " - << last_msg_.certificate_bytes[19]; - EXPECT_EQ(last_msg_.certificate_bytes[20], 60) - << "incorrect value for last_msg_.certificate_bytes[20], expected 60, is " - << last_msg_.certificate_bytes[20]; - EXPECT_EQ(last_msg_.certificate_bytes[21], 63) - << "incorrect value for last_msg_.certificate_bytes[21], expected 63, is " - << last_msg_.certificate_bytes[21]; - EXPECT_EQ(last_msg_.certificate_bytes[22], 66) - << "incorrect value for last_msg_.certificate_bytes[22], expected 66, is " - << last_msg_.certificate_bytes[22]; - EXPECT_EQ(last_msg_.certificate_bytes[23], 69) - << "incorrect value for last_msg_.certificate_bytes[23], expected 69, is " - << last_msg_.certificate_bytes[23]; - EXPECT_EQ(last_msg_.certificate_bytes[24], 72) - << "incorrect value for last_msg_.certificate_bytes[24], expected 72, is " - << last_msg_.certificate_bytes[24]; - EXPECT_EQ(last_msg_.certificate_bytes[25], 75) - << "incorrect value for last_msg_.certificate_bytes[25], expected 75, is " - << last_msg_.certificate_bytes[25]; - EXPECT_EQ(last_msg_.certificate_bytes[26], 78) - << "incorrect value for last_msg_.certificate_bytes[26], expected 78, is " - << last_msg_.certificate_bytes[26]; - EXPECT_EQ(last_msg_.certificate_bytes[27], 81) - << "incorrect value for last_msg_.certificate_bytes[27], expected 81, is " - << last_msg_.certificate_bytes[27]; - EXPECT_EQ(last_msg_.certificate_bytes[28], 84) - << "incorrect value for last_msg_.certificate_bytes[28], expected 84, is " - << last_msg_.certificate_bytes[28]; - EXPECT_EQ(last_msg_.certificate_bytes[29], 87) - << "incorrect value for last_msg_.certificate_bytes[29], expected 87, is " - << last_msg_.certificate_bytes[29]; - EXPECT_EQ(last_msg_.certificate_bytes[30], 90) - << "incorrect value for last_msg_.certificate_bytes[30], expected 90, is " - << last_msg_.certificate_bytes[30]; - EXPECT_EQ(last_msg_.certificate_bytes[31], 93) - << "incorrect value for last_msg_.certificate_bytes[31], expected 93, is " - << last_msg_.certificate_bytes[31]; - EXPECT_EQ(last_msg_.certificate_bytes[32], 96) - << "incorrect value for last_msg_.certificate_bytes[32], expected 96, is " - << last_msg_.certificate_bytes[32]; - EXPECT_EQ(last_msg_.certificate_bytes[33], 99) - << "incorrect value for last_msg_.certificate_bytes[33], expected 99, is " - << last_msg_.certificate_bytes[33]; - EXPECT_EQ(last_msg_.certificate_bytes[34], 102) - << "incorrect value for last_msg_.certificate_bytes[34], expected 102, " - "is " - << last_msg_.certificate_bytes[34]; - EXPECT_EQ(last_msg_.certificate_bytes[35], 105) - << "incorrect value for last_msg_.certificate_bytes[35], expected 105, " - "is " - << last_msg_.certificate_bytes[35]; - EXPECT_EQ(last_msg_.certificate_bytes[36], 108) - << "incorrect value for last_msg_.certificate_bytes[36], expected 108, " - "is " - << last_msg_.certificate_bytes[36]; - EXPECT_EQ(last_msg_.certificate_bytes[37], 111) - << "incorrect value for last_msg_.certificate_bytes[37], expected 111, " - "is " - << last_msg_.certificate_bytes[37]; - EXPECT_EQ(last_msg_.certificate_bytes[38], 114) - << "incorrect value for last_msg_.certificate_bytes[38], expected 114, " - "is " - << last_msg_.certificate_bytes[38]; - EXPECT_EQ(last_msg_.certificate_bytes[39], 117) - << "incorrect value for last_msg_.certificate_bytes[39], expected 117, " - "is " - << last_msg_.certificate_bytes[39]; - EXPECT_EQ(last_msg_.certificate_bytes[40], 120) - << "incorrect value for last_msg_.certificate_bytes[40], expected 120, " - "is " - << last_msg_.certificate_bytes[40]; - EXPECT_EQ(last_msg_.certificate_bytes[41], 123) - << "incorrect value for last_msg_.certificate_bytes[41], expected 123, " - "is " - << last_msg_.certificate_bytes[41]; - EXPECT_EQ(last_msg_.certificate_bytes[42], 126) - << "incorrect value for last_msg_.certificate_bytes[42], expected 126, " - "is " - << last_msg_.certificate_bytes[42]; - EXPECT_EQ(last_msg_.certificate_bytes[43], 129) - << "incorrect value for last_msg_.certificate_bytes[43], expected 129, " - "is " - << last_msg_.certificate_bytes[43]; - EXPECT_EQ(last_msg_.certificate_bytes[44], 132) - << "incorrect value for last_msg_.certificate_bytes[44], expected 132, " - "is " - << last_msg_.certificate_bytes[44]; - EXPECT_EQ(last_msg_.certificate_bytes[45], 135) - << "incorrect value for last_msg_.certificate_bytes[45], expected 135, " - "is " - << last_msg_.certificate_bytes[45]; - EXPECT_EQ(last_msg_.certificate_bytes[46], 138) - << "incorrect value for last_msg_.certificate_bytes[46], expected 138, " - "is " - << last_msg_.certificate_bytes[46]; - EXPECT_EQ(last_msg_.certificate_bytes[47], 141) - << "incorrect value for last_msg_.certificate_bytes[47], expected 141, " - "is " - << last_msg_.certificate_bytes[47]; - EXPECT_EQ(last_msg_.certificate_bytes[48], 144) - << "incorrect value for last_msg_.certificate_bytes[48], expected 144, " - "is " - << last_msg_.certificate_bytes[48]; - EXPECT_EQ(last_msg_.certificate_bytes[49], 147) - << "incorrect value for last_msg_.certificate_bytes[49], expected 147, " - "is " - << last_msg_.certificate_bytes[49]; - EXPECT_EQ(last_msg_.certificate_bytes[50], 150) - << "incorrect value for last_msg_.certificate_bytes[50], expected 150, " - "is " - << last_msg_.certificate_bytes[50]; - EXPECT_EQ(last_msg_.certificate_bytes[51], 153) - << "incorrect value for last_msg_.certificate_bytes[51], expected 153, " - "is " - << last_msg_.certificate_bytes[51]; - EXPECT_EQ(last_msg_.certificate_bytes[52], 156) - << "incorrect value for last_msg_.certificate_bytes[52], expected 156, " - "is " - << last_msg_.certificate_bytes[52]; - EXPECT_EQ(last_msg_.certificate_bytes[53], 159) - << "incorrect value for last_msg_.certificate_bytes[53], expected 159, " - "is " - << last_msg_.certificate_bytes[53]; - EXPECT_EQ(last_msg_.certificate_bytes[54], 162) - << "incorrect value for last_msg_.certificate_bytes[54], expected 162, " - "is " - << last_msg_.certificate_bytes[54]; - EXPECT_EQ(last_msg_.certificate_bytes[55], 165) - << "incorrect value for last_msg_.certificate_bytes[55], expected 165, " - "is " - << last_msg_.certificate_bytes[55]; - EXPECT_EQ(last_msg_.certificate_bytes[56], 168) - << "incorrect value for last_msg_.certificate_bytes[56], expected 168, " - "is " - << last_msg_.certificate_bytes[56]; - EXPECT_EQ(last_msg_.certificate_bytes[57], 171) - << "incorrect value for last_msg_.certificate_bytes[57], expected 171, " - "is " - << last_msg_.certificate_bytes[57]; - EXPECT_EQ(last_msg_.certificate_bytes[58], 174) - << "incorrect value for last_msg_.certificate_bytes[58], expected 174, " - "is " - << last_msg_.certificate_bytes[58]; - EXPECT_EQ(last_msg_.certificate_bytes[59], 177) - << "incorrect value for last_msg_.certificate_bytes[59], expected 177, " - "is " - << last_msg_.certificate_bytes[59]; - EXPECT_EQ(last_msg_.certificate_bytes[60], 180) - << "incorrect value for last_msg_.certificate_bytes[60], expected 180, " - "is " - << last_msg_.certificate_bytes[60]; - EXPECT_EQ(last_msg_.certificate_bytes[61], 183) - << "incorrect value for last_msg_.certificate_bytes[61], expected 183, " - "is " - << last_msg_.certificate_bytes[61]; - EXPECT_EQ(last_msg_.certificate_bytes[62], 186) - << "incorrect value for last_msg_.certificate_bytes[62], expected 186, " - "is " - << last_msg_.certificate_bytes[62]; - EXPECT_EQ(last_msg_.certificate_bytes[63], 189) - << "incorrect value for last_msg_.certificate_bytes[63], expected 189, " - "is " - << last_msg_.certificate_bytes[63]; - EXPECT_EQ(last_msg_.certificate_bytes[64], 192) - << "incorrect value for last_msg_.certificate_bytes[64], expected 192, " - "is " - << last_msg_.certificate_bytes[64]; - EXPECT_EQ(last_msg_.certificate_bytes[65], 195) - << "incorrect value for last_msg_.certificate_bytes[65], expected 195, " - "is " - << last_msg_.certificate_bytes[65]; - EXPECT_EQ(last_msg_.certificate_bytes[66], 198) - << "incorrect value for last_msg_.certificate_bytes[66], expected 198, " - "is " - << last_msg_.certificate_bytes[66]; - EXPECT_EQ(last_msg_.certificate_bytes[67], 201) - << "incorrect value for last_msg_.certificate_bytes[67], expected 201, " - "is " - << last_msg_.certificate_bytes[67]; - EXPECT_EQ(last_msg_.certificate_bytes[68], 204) - << "incorrect value for last_msg_.certificate_bytes[68], expected 204, " - "is " - << last_msg_.certificate_bytes[68]; - EXPECT_EQ(last_msg_.certificate_bytes[69], 207) - << "incorrect value for last_msg_.certificate_bytes[69], expected 207, " - "is " - << last_msg_.certificate_bytes[69]; - EXPECT_EQ(last_msg_.certificate_bytes[70], 210) - << "incorrect value for last_msg_.certificate_bytes[70], expected 210, " - "is " - << last_msg_.certificate_bytes[70]; - EXPECT_EQ(last_msg_.certificate_bytes[71], 213) - << "incorrect value for last_msg_.certificate_bytes[71], expected 213, " - "is " - << last_msg_.certificate_bytes[71]; - EXPECT_EQ(last_msg_.certificate_bytes[72], 216) - << "incorrect value for last_msg_.certificate_bytes[72], expected 216, " - "is " - << last_msg_.certificate_bytes[72]; - EXPECT_EQ(last_msg_.certificate_bytes[73], 219) - << "incorrect value for last_msg_.certificate_bytes[73], expected 219, " - "is " - << last_msg_.certificate_bytes[73]; - EXPECT_EQ(last_msg_.certificate_bytes[74], 222) - << "incorrect value for last_msg_.certificate_bytes[74], expected 222, " - "is " - << last_msg_.certificate_bytes[74]; - EXPECT_EQ(last_msg_.certificate_bytes[75], 225) - << "incorrect value for last_msg_.certificate_bytes[75], expected 225, " - "is " - << last_msg_.certificate_bytes[75]; - EXPECT_EQ(last_msg_.certificate_bytes[76], 228) - << "incorrect value for last_msg_.certificate_bytes[76], expected 228, " - "is " - << last_msg_.certificate_bytes[76]; - EXPECT_EQ(last_msg_.certificate_bytes[77], 231) - << "incorrect value for last_msg_.certificate_bytes[77], expected 231, " - "is " - << last_msg_.certificate_bytes[77]; - EXPECT_EQ(last_msg_.certificate_bytes[78], 234) - << "incorrect value for last_msg_.certificate_bytes[78], expected 234, " - "is " - << last_msg_.certificate_bytes[78]; - EXPECT_EQ(last_msg_.certificate_bytes[79], 237) - << "incorrect value for last_msg_.certificate_bytes[79], expected 237, " - "is " - << last_msg_.certificate_bytes[79]; - EXPECT_EQ(last_msg_.certificate_bytes[80], 240) - << "incorrect value for last_msg_.certificate_bytes[80], expected 240, " - "is " - << last_msg_.certificate_bytes[80]; - EXPECT_EQ(last_msg_.certificate_bytes[81], 243) - << "incorrect value for last_msg_.certificate_bytes[81], expected 243, " - "is " - << last_msg_.certificate_bytes[81]; - EXPECT_EQ(last_msg_.certificate_bytes[82], 246) - << "incorrect value for last_msg_.certificate_bytes[82], expected 246, " - "is " - << last_msg_.certificate_bytes[82]; - EXPECT_EQ(last_msg_.certificate_bytes[83], 249) - << "incorrect value for last_msg_.certificate_bytes[83], expected 249, " - "is " - << last_msg_.certificate_bytes[83]; - EXPECT_EQ(last_msg_.certificate_bytes[84], 252) - << "incorrect value for last_msg_.certificate_bytes[84], expected 252, " - "is " - << last_msg_.certificate_bytes[84]; - EXPECT_EQ(last_msg_.fingerprint[0], 100) - << "incorrect value for last_msg_.fingerprint[0], expected 100, is " - << last_msg_.fingerprint[0]; - EXPECT_EQ(last_msg_.fingerprint[1], 101) - << "incorrect value for last_msg_.fingerprint[1], expected 101, is " - << last_msg_.fingerprint[1]; - EXPECT_EQ(last_msg_.fingerprint[2], 102) - << "incorrect value for last_msg_.fingerprint[2], expected 102, is " - << last_msg_.fingerprint[2]; - EXPECT_EQ(last_msg_.fingerprint[3], 103) - << "incorrect value for last_msg_.fingerprint[3], expected 103, is " - << last_msg_.fingerprint[3]; - EXPECT_EQ(last_msg_.fingerprint[4], 104) - << "incorrect value for last_msg_.fingerprint[4], expected 104, is " - << last_msg_.fingerprint[4]; - EXPECT_EQ(last_msg_.fingerprint[5], 105) - << "incorrect value for last_msg_.fingerprint[5], expected 105, is " - << last_msg_.fingerprint[5]; - EXPECT_EQ(last_msg_.fingerprint[6], 106) - << "incorrect value for last_msg_.fingerprint[6], expected 106, is " - << last_msg_.fingerprint[6]; - EXPECT_EQ(last_msg_.fingerprint[7], 107) - << "incorrect value for last_msg_.fingerprint[7], expected 107, is " - << last_msg_.fingerprint[7]; - EXPECT_EQ(last_msg_.fingerprint[8], 108) - << "incorrect value for last_msg_.fingerprint[8], expected 108, is " - << last_msg_.fingerprint[8]; - EXPECT_EQ(last_msg_.fingerprint[9], 109) - << "incorrect value for last_msg_.fingerprint[9], expected 109, is " - << last_msg_.fingerprint[9]; - EXPECT_EQ(last_msg_.fingerprint[10], 110) - << "incorrect value for last_msg_.fingerprint[10], expected 110, is " - << last_msg_.fingerprint[10]; - EXPECT_EQ(last_msg_.fingerprint[11], 111) - << "incorrect value for last_msg_.fingerprint[11], expected 111, is " - << last_msg_.fingerprint[11]; - EXPECT_EQ(last_msg_.fingerprint[12], 112) - << "incorrect value for last_msg_.fingerprint[12], expected 112, is " - << last_msg_.fingerprint[12]; - EXPECT_EQ(last_msg_.fingerprint[13], 113) - << "incorrect value for last_msg_.fingerprint[13], expected 113, is " - << last_msg_.fingerprint[13]; - EXPECT_EQ(last_msg_.fingerprint[14], 114) - << "incorrect value for last_msg_.fingerprint[14], expected 114, is " - << last_msg_.fingerprint[14]; - EXPECT_EQ(last_msg_.fingerprint[15], 115) - << "incorrect value for last_msg_.fingerprint[15], expected 115, is " - << last_msg_.fingerprint[15]; - EXPECT_EQ(last_msg_.fingerprint[16], 116) - << "incorrect value for last_msg_.fingerprint[16], expected 116, is " - << last_msg_.fingerprint[16]; - EXPECT_EQ(last_msg_.fingerprint[17], 117) - << "incorrect value for last_msg_.fingerprint[17], expected 117, is " - << last_msg_.fingerprint[17]; - EXPECT_EQ(last_msg_.fingerprint[18], 118) - << "incorrect value for last_msg_.fingerprint[18], expected 118, is " - << last_msg_.fingerprint[18]; - EXPECT_EQ(last_msg_.fingerprint[19], 119) - << "incorrect value for last_msg_.fingerprint[19], expected 119, is " - << last_msg_.fingerprint[19]; - EXPECT_EQ(last_msg_.n_certificate_bytes, 85) - << "incorrect value for last_msg_.n_certificate_bytes, expected 85, is " - << last_msg_.n_certificate_bytes; - EXPECT_EQ(last_msg_.n_msg, 16) - << "incorrect value for last_msg_.n_msg, expected 16, is " - << last_msg_.n_msg; + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEd25519CertificateDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519CertificateDep0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEd25519CertificateDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepA.cc b/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepA.cc index 3457bcc595..af7eb50ccb 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepA.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepA.cc @@ -16,66 +16,498 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEd25519SignatureDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEd25519SignatureDepA0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEd25519SignatureDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgEd25519SignatureDepA0() { + assign(test_msg_.fingerprint[0], 100); + + assign(test_msg_.fingerprint[1], 101); + + assign(test_msg_.fingerprint[2], 102); + + assign(test_msg_.fingerprint[3], 103); + + assign(test_msg_.fingerprint[4], 104); + + assign(test_msg_.fingerprint[5], 105); + + assign(test_msg_.fingerprint[6], 106); + + assign(test_msg_.fingerprint[7], 107); + + assign(test_msg_.fingerprint[8], 108); + + assign(test_msg_.fingerprint[9], 109); + + assign(test_msg_.fingerprint[10], 110); + + assign(test_msg_.fingerprint[11], 111); + + assign(test_msg_.fingerprint[12], 112); + + assign(test_msg_.fingerprint[13], 113); + + assign(test_msg_.fingerprint[14], 114); + + assign(test_msg_.fingerprint[15], 115); + + assign(test_msg_.fingerprint[16], 116); + + assign(test_msg_.fingerprint[17], 117); + + assign(test_msg_.fingerprint[18], 118); + + assign(test_msg_.fingerprint[19], 119); + assign(test_msg_.n_signed_messages, 25); + + assign(test_msg_.signature[0], 0); + + assign(test_msg_.signature[1], 1); + + assign(test_msg_.signature[2], 2); + + assign(test_msg_.signature[3], 3); + + assign(test_msg_.signature[4], 4); + + assign(test_msg_.signature[5], 5); + + assign(test_msg_.signature[6], 6); + + assign(test_msg_.signature[7], 7); + + assign(test_msg_.signature[8], 8); + + assign(test_msg_.signature[9], 9); + + assign(test_msg_.signature[10], 10); + + assign(test_msg_.signature[11], 11); + + assign(test_msg_.signature[12], 12); + + assign(test_msg_.signature[13], 13); + + assign(test_msg_.signature[14], 14); + + assign(test_msg_.signature[15], 15); + + assign(test_msg_.signature[16], 16); + + assign(test_msg_.signature[17], 17); + + assign(test_msg_.signature[18], 18); + + assign(test_msg_.signature[19], 19); + + assign(test_msg_.signature[20], 20); + + assign(test_msg_.signature[21], 21); + + assign(test_msg_.signature[22], 22); + + assign(test_msg_.signature[23], 23); + + assign(test_msg_.signature[24], 24); + + assign(test_msg_.signature[25], 25); + + assign(test_msg_.signature[26], 26); + + assign(test_msg_.signature[27], 27); + + assign(test_msg_.signature[28], 28); + + assign(test_msg_.signature[29], 29); + + assign(test_msg_.signature[30], 30); + + assign(test_msg_.signature[31], 31); + + assign(test_msg_.signature[32], 32); + + assign(test_msg_.signature[33], 33); + + assign(test_msg_.signature[34], 34); + + assign(test_msg_.signature[35], 35); + + assign(test_msg_.signature[36], 36); + + assign(test_msg_.signature[37], 37); + + assign(test_msg_.signature[38], 38); + + assign(test_msg_.signature[39], 39); + + assign(test_msg_.signature[40], 40); + + assign(test_msg_.signature[41], 41); + + assign(test_msg_.signature[42], 42); + + assign(test_msg_.signature[43], 43); + + assign(test_msg_.signature[44], 44); + + assign(test_msg_.signature[45], 45); + + assign(test_msg_.signature[46], 46); + + assign(test_msg_.signature[47], 47); + + assign(test_msg_.signature[48], 48); + + assign(test_msg_.signature[49], 49); + + assign(test_msg_.signature[50], 50); + + assign(test_msg_.signature[51], 51); + + assign(test_msg_.signature[52], 52); + + assign(test_msg_.signature[53], 53); + + assign(test_msg_.signature[54], 54); + + assign(test_msg_.signature[55], 55); + + assign(test_msg_.signature[56], 56); + + assign(test_msg_.signature[57], 57); + + assign(test_msg_.signature[58], 58); + + assign(test_msg_.signature[59], 59); + + assign(test_msg_.signature[60], 60); + + assign(test_msg_.signature[61], 61); + + assign(test_msg_.signature[62], 62); + + assign(test_msg_.signature[63], 63); + + assign(test_msg_.signed_messages[0], 5000); + + assign(test_msg_.signed_messages[1], 5234); + + assign(test_msg_.signed_messages[2], 5468); + + assign(test_msg_.signed_messages[3], 5702); + + assign(test_msg_.signed_messages[4], 5936); + + assign(test_msg_.signed_messages[5], 6170); + + assign(test_msg_.signed_messages[6], 6404); + + assign(test_msg_.signed_messages[7], 6638); + + assign(test_msg_.signed_messages[8], 6872); + + assign(test_msg_.signed_messages[9], 7106); + + assign(test_msg_.signed_messages[10], 7340); + + assign(test_msg_.signed_messages[11], 7574); + + assign(test_msg_.signed_messages[12], 7808); + + assign(test_msg_.signed_messages[13], 8042); + + assign(test_msg_.signed_messages[14], 8276); + + assign(test_msg_.signed_messages[15], 8510); + + assign(test_msg_.signed_messages[16], 8744); + + assign(test_msg_.signed_messages[17], 8978); + + assign(test_msg_.signed_messages[18], 9212); + + assign(test_msg_.signed_messages[19], 9446); + + assign(test_msg_.signed_messages[20], 9680); + + assign(test_msg_.signed_messages[21], 9914); + + assign(test_msg_.signed_messages[22], 10148); + + assign(test_msg_.signed_messages[23], 10382); + + assign(test_msg_.signed_messages[24], 10616); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ed25519_signature_dep_a_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_signature_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ed25519_signature_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEd25519SignatureDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_signature_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEd25519SignatureDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ed25519_signature_dep_a, + sizeof(msg->ed25519_signature_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ed25519_signature_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ed25519_signature_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEd25519SignatureDepA); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x6FA9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 184; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ed25519_signature_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ed25519_signature_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ed25519_signature_dep_a_t &lesser, + const sbp_msg_ed25519_signature_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ed25519_signature_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ed25519_signature_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519SignatureDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519SignatureDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEd25519SignatureDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEd25519SignatureDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_signing_MsgEd25519SignatureDepA0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ed25519_signature_dep_a_t test_msg_{}; + uint8_t encoded_frame_[184 + 8] = { 85, 1, 12, 66, 0, 184, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, @@ -90,571 +522,1124 @@ TEST_F(Test_auto_check_sbp_signing_MsgEd25519SignatureDepA0, Test) { 0, 230, 36, 0, 0, 208, 37, 0, 0, 186, 38, 0, 0, 164, 39, 0, 0, 142, 40, 0, 0, 120, 41, 0, 0, 169, 111, }; + uint8_t encoded_payload_[184] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 113, 114, 115, 116, 117, 118, 119, 136, 19, 0, 0, 114, 20, + 0, 0, 92, 21, 0, 0, 70, 22, 0, 0, 48, 23, 0, 0, 26, + 24, 0, 0, 4, 25, 0, 0, 238, 25, 0, 0, 216, 26, 0, 0, + 194, 27, 0, 0, 172, 28, 0, 0, 150, 29, 0, 0, 128, 30, 0, + 0, 106, 31, 0, 0, 84, 32, 0, 0, 62, 33, 0, 0, 40, 34, + 0, 0, 18, 35, 0, 0, 252, 35, 0, 0, 230, 36, 0, 0, 208, + 37, 0, 0, 186, 38, 0, 0, 164, 39, 0, 0, 142, 40, 0, 0, + 120, 41, 0, 0, + }; +}; - sbp_msg_ed25519_signature_dep_a_t test_msg{}; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_encoded_len(&info.test_msg), + info.payload_len); - test_msg.fingerprint[0] = 100; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEd25519SignatureDepA, + &info.test_msg_wrapped), + info.payload_len); +} - test_msg.fingerprint[1] = 101; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[184]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 184); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 184), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEd25519SignatureDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 184); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 184), 0); +} - test_msg.fingerprint[2] = 102; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[184]; - test_msg.fingerprint[3] = 103; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 184), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[184]; + + for (uint8_t i = 0; i < 184; i++) { + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.fingerprint[4] = 104; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 184); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgEd25519SignatureDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 184); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.fingerprint[5] = 105; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_a_t msg{}; - test_msg.fingerprint[6] = 106; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ed25519_signature_dep_a_t t{}; + return sbp_msg_ed25519_signature_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ed25519_signature_dep_a_t t{}; + t.n_signed_messages = 1; + return sbp_msg_ed25519_signature_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} - test_msg.fingerprint[7] = 107; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[8] = 108; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.fingerprint[9] = 109; + CHandler handler{&state}; - test_msg.fingerprint[10] = 110; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.fingerprint[11] = 111; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.fingerprint[12] = 112; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[13] = 113; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.fingerprint[14] = 114; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_a_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.fingerprint[15] = 115; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[16] = 116; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.fingerprint[17] = 117; + EXPECT_EQ(sbp_message_send(&state, SbpMsgEd25519SignatureDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.fingerprint[18] = 118; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, Comparison) { + auto info = get_test_msg_info(); - test_msg.fingerprint[19] = 119; - test_msg.n_signed_messages = 25; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[0], greater.fingerprint[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[0] = 0; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[1], greater.fingerprint[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[1] = 1; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[2], greater.fingerprint[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[2] = 2; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[3], greater.fingerprint[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[3] = 3; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[4], greater.fingerprint[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[4] = 4; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[5], greater.fingerprint[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[5] = 5; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[6], greater.fingerprint[6]); + comparison_tests(lesser, greater); + } - test_msg.signature[6] = 6; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[7], greater.fingerprint[7]); + comparison_tests(lesser, greater); + } - test_msg.signature[7] = 7; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[8], greater.fingerprint[8]); + comparison_tests(lesser, greater); + } - test_msg.signature[8] = 8; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[9], greater.fingerprint[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[10], greater.fingerprint[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[11], greater.fingerprint[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[12], greater.fingerprint[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[13], greater.fingerprint[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[14], greater.fingerprint[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[15], greater.fingerprint[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[16], greater.fingerprint[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[17], greater.fingerprint[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[18], greater.fingerprint[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[19], greater.fingerprint[19]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_signed_messages, greater.n_signed_messages); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[0], greater.signature[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[1], greater.signature[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[2], greater.signature[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[3], greater.signature[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[4], greater.signature[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[5], greater.signature[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[6], greater.signature[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[7], greater.signature[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[8], greater.signature[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[9], greater.signature[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[10], greater.signature[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[11], greater.signature[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[12], greater.signature[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[13], greater.signature[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[9] = 9; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[14], greater.signature[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[10] = 10; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[15], greater.signature[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[16], greater.signature[16]); + comparison_tests(lesser, greater); + } - test_msg.signature[11] = 11; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[17], greater.signature[17]); + comparison_tests(lesser, greater); + } - test_msg.signature[12] = 12; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[18], greater.signature[18]); + comparison_tests(lesser, greater); + } - test_msg.signature[13] = 13; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[19], greater.signature[19]); + comparison_tests(lesser, greater); + } - test_msg.signature[14] = 14; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[20], greater.signature[20]); + comparison_tests(lesser, greater); + } - test_msg.signature[15] = 15; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[21], greater.signature[21]); + comparison_tests(lesser, greater); + } - test_msg.signature[16] = 16; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[22], greater.signature[22]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[23], greater.signature[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[24], greater.signature[24]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[25], greater.signature[25]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[26], greater.signature[26]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[27], greater.signature[27]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[28], greater.signature[28]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[29], greater.signature[29]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[30], greater.signature[30]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[31], greater.signature[31]); + comparison_tests(lesser, greater); + } - test_msg.signature[17] = 17; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[32], greater.signature[32]); + comparison_tests(lesser, greater); + } - test_msg.signature[18] = 18; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[33], greater.signature[33]); + comparison_tests(lesser, greater); + } - test_msg.signature[19] = 19; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[34], greater.signature[34]); + comparison_tests(lesser, greater); + } - test_msg.signature[20] = 20; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[35], greater.signature[35]); + comparison_tests(lesser, greater); + } - test_msg.signature[21] = 21; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[36], greater.signature[36]); + comparison_tests(lesser, greater); + } - test_msg.signature[22] = 22; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[37], greater.signature[37]); + comparison_tests(lesser, greater); + } - test_msg.signature[23] = 23; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[38], greater.signature[38]); + comparison_tests(lesser, greater); + } - test_msg.signature[24] = 24; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[39], greater.signature[39]); + comparison_tests(lesser, greater); + } - test_msg.signature[25] = 25; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[40], greater.signature[40]); + comparison_tests(lesser, greater); + } - test_msg.signature[26] = 26; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[41], greater.signature[41]); + comparison_tests(lesser, greater); + } - test_msg.signature[27] = 27; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[42], greater.signature[42]); + comparison_tests(lesser, greater); + } - test_msg.signature[28] = 28; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[43], greater.signature[43]); + comparison_tests(lesser, greater); + } - test_msg.signature[29] = 29; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[44], greater.signature[44]); + comparison_tests(lesser, greater); + } - test_msg.signature[30] = 30; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[45], greater.signature[45]); + comparison_tests(lesser, greater); + } - test_msg.signature[31] = 31; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[46], greater.signature[46]); + comparison_tests(lesser, greater); + } - test_msg.signature[32] = 32; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[47], greater.signature[47]); + comparison_tests(lesser, greater); + } - test_msg.signature[33] = 33; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[48], greater.signature[48]); + comparison_tests(lesser, greater); + } - test_msg.signature[34] = 34; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[49], greater.signature[49]); + comparison_tests(lesser, greater); + } - test_msg.signature[35] = 35; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[50], greater.signature[50]); + comparison_tests(lesser, greater); + } - test_msg.signature[36] = 36; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[51], greater.signature[51]); + comparison_tests(lesser, greater); + } - test_msg.signature[37] = 37; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[52], greater.signature[52]); + comparison_tests(lesser, greater); + } - test_msg.signature[38] = 38; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[53], greater.signature[53]); + comparison_tests(lesser, greater); + } - test_msg.signature[39] = 39; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[54], greater.signature[54]); + comparison_tests(lesser, greater); + } - test_msg.signature[40] = 40; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[55], greater.signature[55]); + comparison_tests(lesser, greater); + } - test_msg.signature[41] = 41; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[56], greater.signature[56]); + comparison_tests(lesser, greater); + } - test_msg.signature[42] = 42; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[57], greater.signature[57]); + comparison_tests(lesser, greater); + } - test_msg.signature[43] = 43; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[58], greater.signature[58]); + comparison_tests(lesser, greater); + } - test_msg.signature[44] = 44; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[59], greater.signature[59]); + comparison_tests(lesser, greater); + } - test_msg.signature[45] = 45; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[60], greater.signature[60]); + comparison_tests(lesser, greater); + } - test_msg.signature[46] = 46; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[61], greater.signature[61]); + comparison_tests(lesser, greater); + } - test_msg.signature[47] = 47; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[62], greater.signature[62]); + comparison_tests(lesser, greater); + } - test_msg.signature[48] = 48; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signature[63], greater.signature[63]); + comparison_tests(lesser, greater); + } - test_msg.signature[49] = 49; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[0], greater.signed_messages[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[50] = 50; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[1], greater.signed_messages[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[51] = 51; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[2], greater.signed_messages[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[52] = 52; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[3], greater.signed_messages[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[53] = 53; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[4], greater.signed_messages[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[54] = 54; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[5], greater.signed_messages[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[55] = 55; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[6], greater.signed_messages[6]); + comparison_tests(lesser, greater); + } - test_msg.signature[56] = 56; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[7], greater.signed_messages[7]); + comparison_tests(lesser, greater); + } - test_msg.signature[57] = 57; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[8], greater.signed_messages[8]); + comparison_tests(lesser, greater); + } - test_msg.signature[58] = 58; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[9], greater.signed_messages[9]); + comparison_tests(lesser, greater); + } - test_msg.signature[59] = 59; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[10], + greater.signed_messages[10]); + comparison_tests(lesser, greater); + } - test_msg.signature[60] = 60; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[11], + greater.signed_messages[11]); + comparison_tests(lesser, greater); + } - test_msg.signature[61] = 61; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[12], + greater.signed_messages[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[62] = 62; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[13], + greater.signed_messages[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[63] = 63; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[14], + greater.signed_messages[14]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[0] = 5000; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[15], + greater.signed_messages[15]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[1] = 5234; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[16], + greater.signed_messages[16]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[2] = 5468; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[17], + greater.signed_messages[17]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[3] = 5702; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[18], + greater.signed_messages[18]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[4] = 5936; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[19], + greater.signed_messages[19]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[5] = 6170; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[20], + greater.signed_messages[20]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[6] = 6404; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[21], + greater.signed_messages[21]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[7] = 6638; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[22], + greater.signed_messages[22]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[8] = 6872; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[23], + greater.signed_messages[23]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[9] = 7106; + { + sbp_msg_ed25519_signature_dep_a_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[24], + greater.signed_messages[24]); + comparison_tests(lesser, greater); + } +} - test_msg.signed_messages[10] = 7340; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEd25519SignatureDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ED25519_SIGNATURE_DEP_A"); +} - test_msg.signed_messages[11] = 7574; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signed_messages[12] = 7808; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.signed_messages[13] = 8042; + const sbp_msg_ed25519_signature_dep_a_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ed25519_signature_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); - test_msg.signed_messages[14] = 8276; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.signed_messages[15] = 8510; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.signed_messages[16] = 8744; + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ed25519_signature_dep_a, info.test_msg); - test_msg.signed_messages[17] = 8978; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ed25519_signature_dep_a, info.test_msg); +} - test_msg.signed_messages[18] = 9212; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.signed_messages[19] = 9446; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.signed_messages[20] = 9680; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.signed_messages[21] = 9914; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.signed_messages[22] = 10148; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[184]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 184); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 184), 0); +} - test_msg.signed_messages[23] = 10382; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 184); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.signed_messages[24] = 10616; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp::State state{}; + state.set_reader(&reader); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + CppHandler handler{&state}; - while (dummy_rd_ < dummy_wr_) { - process(); + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.fingerprint[0], 100) - << "incorrect value for last_msg_.fingerprint[0], expected 100, is " - << last_msg_.fingerprint[0]; - EXPECT_EQ(last_msg_.fingerprint[1], 101) - << "incorrect value for last_msg_.fingerprint[1], expected 101, is " - << last_msg_.fingerprint[1]; - EXPECT_EQ(last_msg_.fingerprint[2], 102) - << "incorrect value for last_msg_.fingerprint[2], expected 102, is " - << last_msg_.fingerprint[2]; - EXPECT_EQ(last_msg_.fingerprint[3], 103) - << "incorrect value for last_msg_.fingerprint[3], expected 103, is " - << last_msg_.fingerprint[3]; - EXPECT_EQ(last_msg_.fingerprint[4], 104) - << "incorrect value for last_msg_.fingerprint[4], expected 104, is " - << last_msg_.fingerprint[4]; - EXPECT_EQ(last_msg_.fingerprint[5], 105) - << "incorrect value for last_msg_.fingerprint[5], expected 105, is " - << last_msg_.fingerprint[5]; - EXPECT_EQ(last_msg_.fingerprint[6], 106) - << "incorrect value for last_msg_.fingerprint[6], expected 106, is " - << last_msg_.fingerprint[6]; - EXPECT_EQ(last_msg_.fingerprint[7], 107) - << "incorrect value for last_msg_.fingerprint[7], expected 107, is " - << last_msg_.fingerprint[7]; - EXPECT_EQ(last_msg_.fingerprint[8], 108) - << "incorrect value for last_msg_.fingerprint[8], expected 108, is " - << last_msg_.fingerprint[8]; - EXPECT_EQ(last_msg_.fingerprint[9], 109) - << "incorrect value for last_msg_.fingerprint[9], expected 109, is " - << last_msg_.fingerprint[9]; - EXPECT_EQ(last_msg_.fingerprint[10], 110) - << "incorrect value for last_msg_.fingerprint[10], expected 110, is " - << last_msg_.fingerprint[10]; - EXPECT_EQ(last_msg_.fingerprint[11], 111) - << "incorrect value for last_msg_.fingerprint[11], expected 111, is " - << last_msg_.fingerprint[11]; - EXPECT_EQ(last_msg_.fingerprint[12], 112) - << "incorrect value for last_msg_.fingerprint[12], expected 112, is " - << last_msg_.fingerprint[12]; - EXPECT_EQ(last_msg_.fingerprint[13], 113) - << "incorrect value for last_msg_.fingerprint[13], expected 113, is " - << last_msg_.fingerprint[13]; - EXPECT_EQ(last_msg_.fingerprint[14], 114) - << "incorrect value for last_msg_.fingerprint[14], expected 114, is " - << last_msg_.fingerprint[14]; - EXPECT_EQ(last_msg_.fingerprint[15], 115) - << "incorrect value for last_msg_.fingerprint[15], expected 115, is " - << last_msg_.fingerprint[15]; - EXPECT_EQ(last_msg_.fingerprint[16], 116) - << "incorrect value for last_msg_.fingerprint[16], expected 116, is " - << last_msg_.fingerprint[16]; - EXPECT_EQ(last_msg_.fingerprint[17], 117) - << "incorrect value for last_msg_.fingerprint[17], expected 117, is " - << last_msg_.fingerprint[17]; - EXPECT_EQ(last_msg_.fingerprint[18], 118) - << "incorrect value for last_msg_.fingerprint[18], expected 118, is " - << last_msg_.fingerprint[18]; - EXPECT_EQ(last_msg_.fingerprint[19], 119) - << "incorrect value for last_msg_.fingerprint[19], expected 119, is " - << last_msg_.fingerprint[19]; - EXPECT_EQ(last_msg_.n_signed_messages, 25) - << "incorrect value for last_msg_.n_signed_messages, expected 25, is " - << last_msg_.n_signed_messages; - EXPECT_EQ(last_msg_.signature[0], 0) - << "incorrect value for last_msg_.signature[0], expected 0, is " - << last_msg_.signature[0]; - EXPECT_EQ(last_msg_.signature[1], 1) - << "incorrect value for last_msg_.signature[1], expected 1, is " - << last_msg_.signature[1]; - EXPECT_EQ(last_msg_.signature[2], 2) - << "incorrect value for last_msg_.signature[2], expected 2, is " - << last_msg_.signature[2]; - EXPECT_EQ(last_msg_.signature[3], 3) - << "incorrect value for last_msg_.signature[3], expected 3, is " - << last_msg_.signature[3]; - EXPECT_EQ(last_msg_.signature[4], 4) - << "incorrect value for last_msg_.signature[4], expected 4, is " - << last_msg_.signature[4]; - EXPECT_EQ(last_msg_.signature[5], 5) - << "incorrect value for last_msg_.signature[5], expected 5, is " - << last_msg_.signature[5]; - EXPECT_EQ(last_msg_.signature[6], 6) - << "incorrect value for last_msg_.signature[6], expected 6, is " - << last_msg_.signature[6]; - EXPECT_EQ(last_msg_.signature[7], 7) - << "incorrect value for last_msg_.signature[7], expected 7, is " - << last_msg_.signature[7]; - EXPECT_EQ(last_msg_.signature[8], 8) - << "incorrect value for last_msg_.signature[8], expected 8, is " - << last_msg_.signature[8]; - EXPECT_EQ(last_msg_.signature[9], 9) - << "incorrect value for last_msg_.signature[9], expected 9, is " - << last_msg_.signature[9]; - EXPECT_EQ(last_msg_.signature[10], 10) - << "incorrect value for last_msg_.signature[10], expected 10, is " - << last_msg_.signature[10]; - EXPECT_EQ(last_msg_.signature[11], 11) - << "incorrect value for last_msg_.signature[11], expected 11, is " - << last_msg_.signature[11]; - EXPECT_EQ(last_msg_.signature[12], 12) - << "incorrect value for last_msg_.signature[12], expected 12, is " - << last_msg_.signature[12]; - EXPECT_EQ(last_msg_.signature[13], 13) - << "incorrect value for last_msg_.signature[13], expected 13, is " - << last_msg_.signature[13]; - EXPECT_EQ(last_msg_.signature[14], 14) - << "incorrect value for last_msg_.signature[14], expected 14, is " - << last_msg_.signature[14]; - EXPECT_EQ(last_msg_.signature[15], 15) - << "incorrect value for last_msg_.signature[15], expected 15, is " - << last_msg_.signature[15]; - EXPECT_EQ(last_msg_.signature[16], 16) - << "incorrect value for last_msg_.signature[16], expected 16, is " - << last_msg_.signature[16]; - EXPECT_EQ(last_msg_.signature[17], 17) - << "incorrect value for last_msg_.signature[17], expected 17, is " - << last_msg_.signature[17]; - EXPECT_EQ(last_msg_.signature[18], 18) - << "incorrect value for last_msg_.signature[18], expected 18, is " - << last_msg_.signature[18]; - EXPECT_EQ(last_msg_.signature[19], 19) - << "incorrect value for last_msg_.signature[19], expected 19, is " - << last_msg_.signature[19]; - EXPECT_EQ(last_msg_.signature[20], 20) - << "incorrect value for last_msg_.signature[20], expected 20, is " - << last_msg_.signature[20]; - EXPECT_EQ(last_msg_.signature[21], 21) - << "incorrect value for last_msg_.signature[21], expected 21, is " - << last_msg_.signature[21]; - EXPECT_EQ(last_msg_.signature[22], 22) - << "incorrect value for last_msg_.signature[22], expected 22, is " - << last_msg_.signature[22]; - EXPECT_EQ(last_msg_.signature[23], 23) - << "incorrect value for last_msg_.signature[23], expected 23, is " - << last_msg_.signature[23]; - EXPECT_EQ(last_msg_.signature[24], 24) - << "incorrect value for last_msg_.signature[24], expected 24, is " - << last_msg_.signature[24]; - EXPECT_EQ(last_msg_.signature[25], 25) - << "incorrect value for last_msg_.signature[25], expected 25, is " - << last_msg_.signature[25]; - EXPECT_EQ(last_msg_.signature[26], 26) - << "incorrect value for last_msg_.signature[26], expected 26, is " - << last_msg_.signature[26]; - EXPECT_EQ(last_msg_.signature[27], 27) - << "incorrect value for last_msg_.signature[27], expected 27, is " - << last_msg_.signature[27]; - EXPECT_EQ(last_msg_.signature[28], 28) - << "incorrect value for last_msg_.signature[28], expected 28, is " - << last_msg_.signature[28]; - EXPECT_EQ(last_msg_.signature[29], 29) - << "incorrect value for last_msg_.signature[29], expected 29, is " - << last_msg_.signature[29]; - EXPECT_EQ(last_msg_.signature[30], 30) - << "incorrect value for last_msg_.signature[30], expected 30, is " - << last_msg_.signature[30]; - EXPECT_EQ(last_msg_.signature[31], 31) - << "incorrect value for last_msg_.signature[31], expected 31, is " - << last_msg_.signature[31]; - EXPECT_EQ(last_msg_.signature[32], 32) - << "incorrect value for last_msg_.signature[32], expected 32, is " - << last_msg_.signature[32]; - EXPECT_EQ(last_msg_.signature[33], 33) - << "incorrect value for last_msg_.signature[33], expected 33, is " - << last_msg_.signature[33]; - EXPECT_EQ(last_msg_.signature[34], 34) - << "incorrect value for last_msg_.signature[34], expected 34, is " - << last_msg_.signature[34]; - EXPECT_EQ(last_msg_.signature[35], 35) - << "incorrect value for last_msg_.signature[35], expected 35, is " - << last_msg_.signature[35]; - EXPECT_EQ(last_msg_.signature[36], 36) - << "incorrect value for last_msg_.signature[36], expected 36, is " - << last_msg_.signature[36]; - EXPECT_EQ(last_msg_.signature[37], 37) - << "incorrect value for last_msg_.signature[37], expected 37, is " - << last_msg_.signature[37]; - EXPECT_EQ(last_msg_.signature[38], 38) - << "incorrect value for last_msg_.signature[38], expected 38, is " - << last_msg_.signature[38]; - EXPECT_EQ(last_msg_.signature[39], 39) - << "incorrect value for last_msg_.signature[39], expected 39, is " - << last_msg_.signature[39]; - EXPECT_EQ(last_msg_.signature[40], 40) - << "incorrect value for last_msg_.signature[40], expected 40, is " - << last_msg_.signature[40]; - EXPECT_EQ(last_msg_.signature[41], 41) - << "incorrect value for last_msg_.signature[41], expected 41, is " - << last_msg_.signature[41]; - EXPECT_EQ(last_msg_.signature[42], 42) - << "incorrect value for last_msg_.signature[42], expected 42, is " - << last_msg_.signature[42]; - EXPECT_EQ(last_msg_.signature[43], 43) - << "incorrect value for last_msg_.signature[43], expected 43, is " - << last_msg_.signature[43]; - EXPECT_EQ(last_msg_.signature[44], 44) - << "incorrect value for last_msg_.signature[44], expected 44, is " - << last_msg_.signature[44]; - EXPECT_EQ(last_msg_.signature[45], 45) - << "incorrect value for last_msg_.signature[45], expected 45, is " - << last_msg_.signature[45]; - EXPECT_EQ(last_msg_.signature[46], 46) - << "incorrect value for last_msg_.signature[46], expected 46, is " - << last_msg_.signature[46]; - EXPECT_EQ(last_msg_.signature[47], 47) - << "incorrect value for last_msg_.signature[47], expected 47, is " - << last_msg_.signature[47]; - EXPECT_EQ(last_msg_.signature[48], 48) - << "incorrect value for last_msg_.signature[48], expected 48, is " - << last_msg_.signature[48]; - EXPECT_EQ(last_msg_.signature[49], 49) - << "incorrect value for last_msg_.signature[49], expected 49, is " - << last_msg_.signature[49]; - EXPECT_EQ(last_msg_.signature[50], 50) - << "incorrect value for last_msg_.signature[50], expected 50, is " - << last_msg_.signature[50]; - EXPECT_EQ(last_msg_.signature[51], 51) - << "incorrect value for last_msg_.signature[51], expected 51, is " - << last_msg_.signature[51]; - EXPECT_EQ(last_msg_.signature[52], 52) - << "incorrect value for last_msg_.signature[52], expected 52, is " - << last_msg_.signature[52]; - EXPECT_EQ(last_msg_.signature[53], 53) - << "incorrect value for last_msg_.signature[53], expected 53, is " - << last_msg_.signature[53]; - EXPECT_EQ(last_msg_.signature[54], 54) - << "incorrect value for last_msg_.signature[54], expected 54, is " - << last_msg_.signature[54]; - EXPECT_EQ(last_msg_.signature[55], 55) - << "incorrect value for last_msg_.signature[55], expected 55, is " - << last_msg_.signature[55]; - EXPECT_EQ(last_msg_.signature[56], 56) - << "incorrect value for last_msg_.signature[56], expected 56, is " - << last_msg_.signature[56]; - EXPECT_EQ(last_msg_.signature[57], 57) - << "incorrect value for last_msg_.signature[57], expected 57, is " - << last_msg_.signature[57]; - EXPECT_EQ(last_msg_.signature[58], 58) - << "incorrect value for last_msg_.signature[58], expected 58, is " - << last_msg_.signature[58]; - EXPECT_EQ(last_msg_.signature[59], 59) - << "incorrect value for last_msg_.signature[59], expected 59, is " - << last_msg_.signature[59]; - EXPECT_EQ(last_msg_.signature[60], 60) - << "incorrect value for last_msg_.signature[60], expected 60, is " - << last_msg_.signature[60]; - EXPECT_EQ(last_msg_.signature[61], 61) - << "incorrect value for last_msg_.signature[61], expected 61, is " - << last_msg_.signature[61]; - EXPECT_EQ(last_msg_.signature[62], 62) - << "incorrect value for last_msg_.signature[62], expected 62, is " - << last_msg_.signature[62]; - EXPECT_EQ(last_msg_.signature[63], 63) - << "incorrect value for last_msg_.signature[63], expected 63, is " - << last_msg_.signature[63]; - EXPECT_EQ(last_msg_.signed_messages[0], 5000) - << "incorrect value for last_msg_.signed_messages[0], expected 5000, is " - << last_msg_.signed_messages[0]; - EXPECT_EQ(last_msg_.signed_messages[1], 5234) - << "incorrect value for last_msg_.signed_messages[1], expected 5234, is " - << last_msg_.signed_messages[1]; - EXPECT_EQ(last_msg_.signed_messages[2], 5468) - << "incorrect value for last_msg_.signed_messages[2], expected 5468, is " - << last_msg_.signed_messages[2]; - EXPECT_EQ(last_msg_.signed_messages[3], 5702) - << "incorrect value for last_msg_.signed_messages[3], expected 5702, is " - << last_msg_.signed_messages[3]; - EXPECT_EQ(last_msg_.signed_messages[4], 5936) - << "incorrect value for last_msg_.signed_messages[4], expected 5936, is " - << last_msg_.signed_messages[4]; - EXPECT_EQ(last_msg_.signed_messages[5], 6170) - << "incorrect value for last_msg_.signed_messages[5], expected 6170, is " - << last_msg_.signed_messages[5]; - EXPECT_EQ(last_msg_.signed_messages[6], 6404) - << "incorrect value for last_msg_.signed_messages[6], expected 6404, is " - << last_msg_.signed_messages[6]; - EXPECT_EQ(last_msg_.signed_messages[7], 6638) - << "incorrect value for last_msg_.signed_messages[7], expected 6638, is " - << last_msg_.signed_messages[7]; - EXPECT_EQ(last_msg_.signed_messages[8], 6872) - << "incorrect value for last_msg_.signed_messages[8], expected 6872, is " - << last_msg_.signed_messages[8]; - EXPECT_EQ(last_msg_.signed_messages[9], 7106) - << "incorrect value for last_msg_.signed_messages[9], expected 7106, is " - << last_msg_.signed_messages[9]; - EXPECT_EQ(last_msg_.signed_messages[10], 7340) - << "incorrect value for last_msg_.signed_messages[10], expected 7340, is " - << last_msg_.signed_messages[10]; - EXPECT_EQ(last_msg_.signed_messages[11], 7574) - << "incorrect value for last_msg_.signed_messages[11], expected 7574, is " - << last_msg_.signed_messages[11]; - EXPECT_EQ(last_msg_.signed_messages[12], 7808) - << "incorrect value for last_msg_.signed_messages[12], expected 7808, is " - << last_msg_.signed_messages[12]; - EXPECT_EQ(last_msg_.signed_messages[13], 8042) - << "incorrect value for last_msg_.signed_messages[13], expected 8042, is " - << last_msg_.signed_messages[13]; - EXPECT_EQ(last_msg_.signed_messages[14], 8276) - << "incorrect value for last_msg_.signed_messages[14], expected 8276, is " - << last_msg_.signed_messages[14]; - EXPECT_EQ(last_msg_.signed_messages[15], 8510) - << "incorrect value for last_msg_.signed_messages[15], expected 8510, is " - << last_msg_.signed_messages[15]; - EXPECT_EQ(last_msg_.signed_messages[16], 8744) - << "incorrect value for last_msg_.signed_messages[16], expected 8744, is " - << last_msg_.signed_messages[16]; - EXPECT_EQ(last_msg_.signed_messages[17], 8978) - << "incorrect value for last_msg_.signed_messages[17], expected 8978, is " - << last_msg_.signed_messages[17]; - EXPECT_EQ(last_msg_.signed_messages[18], 9212) - << "incorrect value for last_msg_.signed_messages[18], expected 9212, is " - << last_msg_.signed_messages[18]; - EXPECT_EQ(last_msg_.signed_messages[19], 9446) - << "incorrect value for last_msg_.signed_messages[19], expected 9446, is " - << last_msg_.signed_messages[19]; - EXPECT_EQ(last_msg_.signed_messages[20], 9680) - << "incorrect value for last_msg_.signed_messages[20], expected 9680, is " - << last_msg_.signed_messages[20]; - EXPECT_EQ(last_msg_.signed_messages[21], 9914) - << "incorrect value for last_msg_.signed_messages[21], expected 9914, is " - << last_msg_.signed_messages[21]; - EXPECT_EQ(last_msg_.signed_messages[22], 10148) - << "incorrect value for last_msg_.signed_messages[22], expected 10148, " - "is " - << last_msg_.signed_messages[22]; - EXPECT_EQ(last_msg_.signed_messages[23], 10382) - << "incorrect value for last_msg_.signed_messages[23], expected 10382, " - "is " - << last_msg_.signed_messages[23]; - EXPECT_EQ(last_msg_.signed_messages[24], 10616) - << "incorrect value for last_msg_.signed_messages[24], expected 10616, " - "is " - << last_msg_.signed_messages[24]; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEd25519SignatureDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEd25519SignatureDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepB.cc b/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepB.cc index 5431af2e45..103313dbac 100644 --- a/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepB.cc +++ b/c/test/cpp/auto_check_sbp_signing_MsgEd25519SignatureDepB.cc @@ -16,66 +16,500 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_signing_MsgEd25519SignatureDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_signing_MsgEd25519SignatureDepB0 + : public ::testing::Test { public: - Test_auto_check_sbp_signing_MsgEd25519SignatureDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_signing_MsgEd25519SignatureDepB0() { + assign(test_msg_.fingerprint[0], 100); + + assign(test_msg_.fingerprint[1], 101); + + assign(test_msg_.fingerprint[2], 102); + + assign(test_msg_.fingerprint[3], 103); + + assign(test_msg_.fingerprint[4], 104); + + assign(test_msg_.fingerprint[5], 105); + + assign(test_msg_.fingerprint[6], 106); + + assign(test_msg_.fingerprint[7], 107); + + assign(test_msg_.fingerprint[8], 108); + + assign(test_msg_.fingerprint[9], 109); + + assign(test_msg_.fingerprint[10], 110); + + assign(test_msg_.fingerprint[11], 111); + + assign(test_msg_.fingerprint[12], 112); + + assign(test_msg_.fingerprint[13], 113); + + assign(test_msg_.fingerprint[14], 114); + + assign(test_msg_.fingerprint[15], 115); + + assign(test_msg_.fingerprint[16], 116); + + assign(test_msg_.fingerprint[17], 117); + + assign(test_msg_.fingerprint[18], 118); + + assign(test_msg_.fingerprint[19], 119); + assign(test_msg_.n_signed_messages, 25); + assign(test_msg_.on_demand_counter, 0); + + assign(test_msg_.signature[0], 0); + + assign(test_msg_.signature[1], 1); + + assign(test_msg_.signature[2], 2); + + assign(test_msg_.signature[3], 3); + + assign(test_msg_.signature[4], 4); + + assign(test_msg_.signature[5], 5); + + assign(test_msg_.signature[6], 6); + + assign(test_msg_.signature[7], 7); + + assign(test_msg_.signature[8], 8); + + assign(test_msg_.signature[9], 9); + + assign(test_msg_.signature[10], 10); + + assign(test_msg_.signature[11], 11); + + assign(test_msg_.signature[12], 12); + + assign(test_msg_.signature[13], 13); + + assign(test_msg_.signature[14], 14); + + assign(test_msg_.signature[15], 15); + + assign(test_msg_.signature[16], 16); + + assign(test_msg_.signature[17], 17); + + assign(test_msg_.signature[18], 18); + + assign(test_msg_.signature[19], 19); + + assign(test_msg_.signature[20], 20); + + assign(test_msg_.signature[21], 21); + + assign(test_msg_.signature[22], 22); + + assign(test_msg_.signature[23], 23); + + assign(test_msg_.signature[24], 24); + + assign(test_msg_.signature[25], 25); + + assign(test_msg_.signature[26], 26); + + assign(test_msg_.signature[27], 27); + + assign(test_msg_.signature[28], 28); + + assign(test_msg_.signature[29], 29); + + assign(test_msg_.signature[30], 30); + + assign(test_msg_.signature[31], 31); + + assign(test_msg_.signature[32], 32); + + assign(test_msg_.signature[33], 33); + + assign(test_msg_.signature[34], 34); + + assign(test_msg_.signature[35], 35); + + assign(test_msg_.signature[36], 36); + + assign(test_msg_.signature[37], 37); + + assign(test_msg_.signature[38], 38); + + assign(test_msg_.signature[39], 39); + + assign(test_msg_.signature[40], 40); + + assign(test_msg_.signature[41], 41); + + assign(test_msg_.signature[42], 42); + + assign(test_msg_.signature[43], 43); + + assign(test_msg_.signature[44], 44); + + assign(test_msg_.signature[45], 45); + + assign(test_msg_.signature[46], 46); + + assign(test_msg_.signature[47], 47); + + assign(test_msg_.signature[48], 48); + + assign(test_msg_.signature[49], 49); + + assign(test_msg_.signature[50], 50); + + assign(test_msg_.signature[51], 51); + + assign(test_msg_.signature[52], 52); + + assign(test_msg_.signature[53], 53); + + assign(test_msg_.signature[54], 54); + + assign(test_msg_.signature[55], 55); + + assign(test_msg_.signature[56], 56); + + assign(test_msg_.signature[57], 57); + + assign(test_msg_.signature[58], 58); + + assign(test_msg_.signature[59], 59); + + assign(test_msg_.signature[60], 60); + + assign(test_msg_.signature[61], 61); + + assign(test_msg_.signature[62], 62); + + assign(test_msg_.signature[63], 63); + + assign(test_msg_.signed_messages[0], 5000); + + assign(test_msg_.signed_messages[1], 5234); + + assign(test_msg_.signed_messages[2], 5468); + + assign(test_msg_.signed_messages[3], 5702); + + assign(test_msg_.signed_messages[4], 5936); + + assign(test_msg_.signed_messages[5], 6170); + + assign(test_msg_.signed_messages[6], 6404); + + assign(test_msg_.signed_messages[7], 6638); + + assign(test_msg_.signed_messages[8], 6872); + + assign(test_msg_.signed_messages[9], 7106); + + assign(test_msg_.signed_messages[10], 7340); + + assign(test_msg_.signed_messages[11], 7574); + + assign(test_msg_.signed_messages[12], 7808); + + assign(test_msg_.signed_messages[13], 8042); + + assign(test_msg_.signed_messages[14], 8276); + + assign(test_msg_.signed_messages[15], 8510); + + assign(test_msg_.signed_messages[16], 8744); + + assign(test_msg_.signed_messages[17], 8978); + + assign(test_msg_.signed_messages[18], 9212); + + assign(test_msg_.signed_messages[19], 9446); + + assign(test_msg_.signed_messages[20], 9680); + + assign(test_msg_.signed_messages[21], 9914); + + assign(test_msg_.signed_messages[22], 10148); + + assign(test_msg_.signed_messages[23], 10382); + + assign(test_msg_.signed_messages[24], 10616); + assign(test_msg_.stream_counter, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ed25519_signature_dep_b_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_signature_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ed25519_signature_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgEd25519SignatureDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ed25519_signature_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgEd25519SignatureDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ed25519_signature_dep_b, + sizeof(msg->ed25519_signature_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ed25519_signature_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ed25519_signature_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgEd25519SignatureDepB); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x91EE; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 186; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ed25519_signature_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ed25519_signature_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ed25519_signature_dep_b_t &lesser, + const sbp_msg_ed25519_signature_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ed25519_signature_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ed25519_signature_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519SignatureDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgEd25519SignatureDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgEd25519SignatureDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgEd25519SignatureDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_signing_MsgEd25519SignatureDepB0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ed25519_signature_dep_b_t test_msg_{}; + uint8_t encoded_frame_[186 + 8] = { 85, 3, 12, 66, 0, 186, 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, @@ -90,579 +524,1136 @@ TEST_F(Test_auto_check_sbp_signing_MsgEd25519SignatureDepB0, Test) { 35, 0, 0, 230, 36, 0, 0, 208, 37, 0, 0, 186, 38, 0, 0, 164, 39, 0, 0, 142, 40, 0, 0, 120, 41, 0, 0, 238, 145, }; + uint8_t encoded_payload_[186] = { + 1, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 100, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 136, 19, 0, 0, + 114, 20, 0, 0, 92, 21, 0, 0, 70, 22, 0, 0, 48, 23, 0, + 0, 26, 24, 0, 0, 4, 25, 0, 0, 238, 25, 0, 0, 216, 26, + 0, 0, 194, 27, 0, 0, 172, 28, 0, 0, 150, 29, 0, 0, 128, + 30, 0, 0, 106, 31, 0, 0, 84, 32, 0, 0, 62, 33, 0, 0, + 40, 34, 0, 0, 18, 35, 0, 0, 252, 35, 0, 0, 230, 36, 0, + 0, 208, 37, 0, 0, 186, 38, 0, 0, 164, 39, 0, 0, 142, 40, + 0, 0, 120, 41, 0, 0, + }; +}; - sbp_msg_ed25519_signature_dep_b_t test_msg{}; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_encoded_len(&info.test_msg), + info.payload_len); - test_msg.fingerprint[0] = 100; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgEd25519SignatureDepB, + &info.test_msg_wrapped), + info.payload_len); +} - test_msg.fingerprint[1] = 101; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[186]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 186); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 186), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgEd25519SignatureDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 186); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 186), 0); +} - test_msg.fingerprint[2] = 102; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[186]; - test_msg.fingerprint[3] = 103; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 186), 0); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[186]; + + for (uint8_t i = 0; i < 186; i++) { + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} - test_msg.fingerprint[4] = 104; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 186); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgEd25519SignatureDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 186); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.fingerprint[5] = 105; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_b_t msg{}; - test_msg.fingerprint[6] = 106; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ed25519_signature_dep_b_t t{}; + return sbp_msg_ed25519_signature_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ed25519_signature_dep_b_t t{}; + t.n_signed_messages = 1; + return sbp_msg_ed25519_signature_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} - test_msg.fingerprint[7] = 107; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[8] = 108; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.fingerprint[9] = 109; + CHandler handler{&state}; - test_msg.fingerprint[10] = 110; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.fingerprint[11] = 111; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.fingerprint[12] = 112; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[13] = 113; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.fingerprint[14] = 114; + EXPECT_EQ(sbp_msg_ed25519_signature_dep_b_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.fingerprint[15] = 115; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.fingerprint[16] = 116; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.fingerprint[17] = 117; + EXPECT_EQ(sbp_message_send(&state, SbpMsgEd25519SignatureDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.fingerprint[18] = 118; +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, Comparison) { + auto info = get_test_msg_info(); - test_msg.fingerprint[19] = 119; - test_msg.n_signed_messages = 25; - test_msg.on_demand_counter = 0; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[0], greater.fingerprint[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[0] = 0; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[1], greater.fingerprint[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[1] = 1; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[2], greater.fingerprint[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[2] = 2; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[3], greater.fingerprint[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[3] = 3; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[4], greater.fingerprint[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[4] = 4; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[5], greater.fingerprint[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[5] = 5; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[6], greater.fingerprint[6]); + comparison_tests(lesser, greater); + } - test_msg.signature[6] = 6; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[7], greater.fingerprint[7]); + comparison_tests(lesser, greater); + } - test_msg.signature[7] = 7; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[8], greater.fingerprint[8]); + comparison_tests(lesser, greater); + } - test_msg.signature[8] = 8; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[9], greater.fingerprint[9]); + comparison_tests(lesser, greater); + } - test_msg.signature[9] = 9; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[10], greater.fingerprint[10]); + comparison_tests(lesser, greater); + } - test_msg.signature[10] = 10; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[11], greater.fingerprint[11]); + comparison_tests(lesser, greater); + } - test_msg.signature[11] = 11; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[12], greater.fingerprint[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[12] = 12; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[13], greater.fingerprint[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[13] = 13; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[14], greater.fingerprint[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[14] = 14; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[15], greater.fingerprint[15]); + comparison_tests(lesser, greater); + } - test_msg.signature[15] = 15; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[16], greater.fingerprint[16]); + comparison_tests(lesser, greater); + } - test_msg.signature[16] = 16; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[17], greater.fingerprint[17]); + comparison_tests(lesser, greater); + } - test_msg.signature[17] = 17; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[18], greater.fingerprint[18]); + comparison_tests(lesser, greater); + } - test_msg.signature[18] = 18; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.fingerprint[19], greater.fingerprint[19]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_signed_messages, greater.n_signed_messages); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.on_demand_counter, greater.on_demand_counter); + comparison_tests(lesser, greater); + } - test_msg.signature[19] = 19; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[0], greater.signature[0]); + comparison_tests(lesser, greater); + } - test_msg.signature[20] = 20; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[1], greater.signature[1]); + comparison_tests(lesser, greater); + } - test_msg.signature[21] = 21; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[2], greater.signature[2]); + comparison_tests(lesser, greater); + } - test_msg.signature[22] = 22; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[3], greater.signature[3]); + comparison_tests(lesser, greater); + } - test_msg.signature[23] = 23; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[4], greater.signature[4]); + comparison_tests(lesser, greater); + } - test_msg.signature[24] = 24; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[5], greater.signature[5]); + comparison_tests(lesser, greater); + } - test_msg.signature[25] = 25; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[6], greater.signature[6]); + comparison_tests(lesser, greater); + } - test_msg.signature[26] = 26; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[7], greater.signature[7]); + comparison_tests(lesser, greater); + } - test_msg.signature[27] = 27; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[8], greater.signature[8]); + comparison_tests(lesser, greater); + } - test_msg.signature[28] = 28; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[9], greater.signature[9]); + comparison_tests(lesser, greater); + } - test_msg.signature[29] = 29; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[10], greater.signature[10]); + comparison_tests(lesser, greater); + } - test_msg.signature[30] = 30; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[11], greater.signature[11]); + comparison_tests(lesser, greater); + } - test_msg.signature[31] = 31; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[12], greater.signature[12]); + comparison_tests(lesser, greater); + } - test_msg.signature[32] = 32; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[13], greater.signature[13]); + comparison_tests(lesser, greater); + } - test_msg.signature[33] = 33; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[14], greater.signature[14]); + comparison_tests(lesser, greater); + } - test_msg.signature[34] = 34; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[15], greater.signature[15]); + comparison_tests(lesser, greater); + } - test_msg.signature[35] = 35; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[16], greater.signature[16]); + comparison_tests(lesser, greater); + } - test_msg.signature[36] = 36; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[17], greater.signature[17]); + comparison_tests(lesser, greater); + } - test_msg.signature[37] = 37; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[18], greater.signature[18]); + comparison_tests(lesser, greater); + } - test_msg.signature[38] = 38; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[19], greater.signature[19]); + comparison_tests(lesser, greater); + } - test_msg.signature[39] = 39; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[20], greater.signature[20]); + comparison_tests(lesser, greater); + } - test_msg.signature[40] = 40; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[21], greater.signature[21]); + comparison_tests(lesser, greater); + } - test_msg.signature[41] = 41; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[22], greater.signature[22]); + comparison_tests(lesser, greater); + } - test_msg.signature[42] = 42; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[23], greater.signature[23]); + comparison_tests(lesser, greater); + } - test_msg.signature[43] = 43; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[24], greater.signature[24]); + comparison_tests(lesser, greater); + } - test_msg.signature[44] = 44; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[25], greater.signature[25]); + comparison_tests(lesser, greater); + } - test_msg.signature[45] = 45; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[26], greater.signature[26]); + comparison_tests(lesser, greater); + } - test_msg.signature[46] = 46; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[27], greater.signature[27]); + comparison_tests(lesser, greater); + } - test_msg.signature[47] = 47; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[28], greater.signature[28]); + comparison_tests(lesser, greater); + } - test_msg.signature[48] = 48; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[29], greater.signature[29]); + comparison_tests(lesser, greater); + } - test_msg.signature[49] = 49; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[30], greater.signature[30]); + comparison_tests(lesser, greater); + } - test_msg.signature[50] = 50; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[31], greater.signature[31]); + comparison_tests(lesser, greater); + } - test_msg.signature[51] = 51; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[32], greater.signature[32]); + comparison_tests(lesser, greater); + } - test_msg.signature[52] = 52; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[33], greater.signature[33]); + comparison_tests(lesser, greater); + } - test_msg.signature[53] = 53; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[34], greater.signature[34]); + comparison_tests(lesser, greater); + } - test_msg.signature[54] = 54; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[35], greater.signature[35]); + comparison_tests(lesser, greater); + } - test_msg.signature[55] = 55; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[36], greater.signature[36]); + comparison_tests(lesser, greater); + } - test_msg.signature[56] = 56; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[37], greater.signature[37]); + comparison_tests(lesser, greater); + } - test_msg.signature[57] = 57; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[38], greater.signature[38]); + comparison_tests(lesser, greater); + } - test_msg.signature[58] = 58; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[39], greater.signature[39]); + comparison_tests(lesser, greater); + } - test_msg.signature[59] = 59; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[40], greater.signature[40]); + comparison_tests(lesser, greater); + } - test_msg.signature[60] = 60; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[41], greater.signature[41]); + comparison_tests(lesser, greater); + } - test_msg.signature[61] = 61; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[42], greater.signature[42]); + comparison_tests(lesser, greater); + } - test_msg.signature[62] = 62; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[43], greater.signature[43]); + comparison_tests(lesser, greater); + } - test_msg.signature[63] = 63; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[44], greater.signature[44]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[0] = 5000; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[45], greater.signature[45]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[1] = 5234; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[46], greater.signature[46]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[2] = 5468; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[47], greater.signature[47]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[3] = 5702; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[48], greater.signature[48]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[4] = 5936; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[49], greater.signature[49]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[5] = 6170; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[50], greater.signature[50]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[6] = 6404; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[51], greater.signature[51]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[7] = 6638; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[52], greater.signature[52]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[8] = 6872; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[53], greater.signature[53]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[9] = 7106; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[54], greater.signature[54]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[10] = 7340; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[55], greater.signature[55]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[11] = 7574; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[56], greater.signature[56]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[12] = 7808; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[57], greater.signature[57]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[13] = 8042; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[58], greater.signature[58]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[14] = 8276; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[59], greater.signature[59]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[15] = 8510; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[60], greater.signature[60]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[16] = 8744; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[61], greater.signature[61]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[17] = 8978; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[62], greater.signature[62]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[18] = 9212; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signature[63], greater.signature[63]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[19] = 9446; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[0], greater.signed_messages[0]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[20] = 9680; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[1], greater.signed_messages[1]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[21] = 9914; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[2], greater.signed_messages[2]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[22] = 10148; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[3], greater.signed_messages[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[4], greater.signed_messages[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[5], greater.signed_messages[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[6], greater.signed_messages[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[7], greater.signed_messages[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[8], greater.signed_messages[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[9], greater.signed_messages[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[10], + greater.signed_messages[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[11], + greater.signed_messages[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[12], + greater.signed_messages[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[13], + greater.signed_messages[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[14], + greater.signed_messages[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[15], + greater.signed_messages[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[16], + greater.signed_messages[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[17], + greater.signed_messages[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[18], + greater.signed_messages[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[19], + greater.signed_messages[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[20], + greater.signed_messages[20]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[21], + greater.signed_messages[21]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[22], + greater.signed_messages[22]); + comparison_tests(lesser, greater); + } - test_msg.signed_messages[23] = 10382; + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[23], + greater.signed_messages[23]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.signed_messages[24], + greater.signed_messages[24]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ed25519_signature_dep_b_t lesser = info.test_msg; + sbp_msg_ed25519_signature_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.stream_counter, greater.stream_counter); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgEd25519SignatureDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_ED25519_SIGNATURE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ed25519_signature_dep_b_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ed25519_signature_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); - test_msg.signed_messages[24] = 10616; - test_msg.stream_counter = 1; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ed25519_signature_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ed25519_signature_dep_b, info.test_msg); +} - EXPECT_EQ(send_message(66, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[186]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 186); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 186), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ed25519_signature_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 186); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.fingerprint[0], 100) - << "incorrect value for last_msg_.fingerprint[0], expected 100, is " - << last_msg_.fingerprint[0]; - EXPECT_EQ(last_msg_.fingerprint[1], 101) - << "incorrect value for last_msg_.fingerprint[1], expected 101, is " - << last_msg_.fingerprint[1]; - EXPECT_EQ(last_msg_.fingerprint[2], 102) - << "incorrect value for last_msg_.fingerprint[2], expected 102, is " - << last_msg_.fingerprint[2]; - EXPECT_EQ(last_msg_.fingerprint[3], 103) - << "incorrect value for last_msg_.fingerprint[3], expected 103, is " - << last_msg_.fingerprint[3]; - EXPECT_EQ(last_msg_.fingerprint[4], 104) - << "incorrect value for last_msg_.fingerprint[4], expected 104, is " - << last_msg_.fingerprint[4]; - EXPECT_EQ(last_msg_.fingerprint[5], 105) - << "incorrect value for last_msg_.fingerprint[5], expected 105, is " - << last_msg_.fingerprint[5]; - EXPECT_EQ(last_msg_.fingerprint[6], 106) - << "incorrect value for last_msg_.fingerprint[6], expected 106, is " - << last_msg_.fingerprint[6]; - EXPECT_EQ(last_msg_.fingerprint[7], 107) - << "incorrect value for last_msg_.fingerprint[7], expected 107, is " - << last_msg_.fingerprint[7]; - EXPECT_EQ(last_msg_.fingerprint[8], 108) - << "incorrect value for last_msg_.fingerprint[8], expected 108, is " - << last_msg_.fingerprint[8]; - EXPECT_EQ(last_msg_.fingerprint[9], 109) - << "incorrect value for last_msg_.fingerprint[9], expected 109, is " - << last_msg_.fingerprint[9]; - EXPECT_EQ(last_msg_.fingerprint[10], 110) - << "incorrect value for last_msg_.fingerprint[10], expected 110, is " - << last_msg_.fingerprint[10]; - EXPECT_EQ(last_msg_.fingerprint[11], 111) - << "incorrect value for last_msg_.fingerprint[11], expected 111, is " - << last_msg_.fingerprint[11]; - EXPECT_EQ(last_msg_.fingerprint[12], 112) - << "incorrect value for last_msg_.fingerprint[12], expected 112, is " - << last_msg_.fingerprint[12]; - EXPECT_EQ(last_msg_.fingerprint[13], 113) - << "incorrect value for last_msg_.fingerprint[13], expected 113, is " - << last_msg_.fingerprint[13]; - EXPECT_EQ(last_msg_.fingerprint[14], 114) - << "incorrect value for last_msg_.fingerprint[14], expected 114, is " - << last_msg_.fingerprint[14]; - EXPECT_EQ(last_msg_.fingerprint[15], 115) - << "incorrect value for last_msg_.fingerprint[15], expected 115, is " - << last_msg_.fingerprint[15]; - EXPECT_EQ(last_msg_.fingerprint[16], 116) - << "incorrect value for last_msg_.fingerprint[16], expected 116, is " - << last_msg_.fingerprint[16]; - EXPECT_EQ(last_msg_.fingerprint[17], 117) - << "incorrect value for last_msg_.fingerprint[17], expected 117, is " - << last_msg_.fingerprint[17]; - EXPECT_EQ(last_msg_.fingerprint[18], 118) - << "incorrect value for last_msg_.fingerprint[18], expected 118, is " - << last_msg_.fingerprint[18]; - EXPECT_EQ(last_msg_.fingerprint[19], 119) - << "incorrect value for last_msg_.fingerprint[19], expected 119, is " - << last_msg_.fingerprint[19]; - EXPECT_EQ(last_msg_.n_signed_messages, 25) - << "incorrect value for last_msg_.n_signed_messages, expected 25, is " - << last_msg_.n_signed_messages; - EXPECT_EQ(last_msg_.on_demand_counter, 0) - << "incorrect value for last_msg_.on_demand_counter, expected 0, is " - << last_msg_.on_demand_counter; - EXPECT_EQ(last_msg_.signature[0], 0) - << "incorrect value for last_msg_.signature[0], expected 0, is " - << last_msg_.signature[0]; - EXPECT_EQ(last_msg_.signature[1], 1) - << "incorrect value for last_msg_.signature[1], expected 1, is " - << last_msg_.signature[1]; - EXPECT_EQ(last_msg_.signature[2], 2) - << "incorrect value for last_msg_.signature[2], expected 2, is " - << last_msg_.signature[2]; - EXPECT_EQ(last_msg_.signature[3], 3) - << "incorrect value for last_msg_.signature[3], expected 3, is " - << last_msg_.signature[3]; - EXPECT_EQ(last_msg_.signature[4], 4) - << "incorrect value for last_msg_.signature[4], expected 4, is " - << last_msg_.signature[4]; - EXPECT_EQ(last_msg_.signature[5], 5) - << "incorrect value for last_msg_.signature[5], expected 5, is " - << last_msg_.signature[5]; - EXPECT_EQ(last_msg_.signature[6], 6) - << "incorrect value for last_msg_.signature[6], expected 6, is " - << last_msg_.signature[6]; - EXPECT_EQ(last_msg_.signature[7], 7) - << "incorrect value for last_msg_.signature[7], expected 7, is " - << last_msg_.signature[7]; - EXPECT_EQ(last_msg_.signature[8], 8) - << "incorrect value for last_msg_.signature[8], expected 8, is " - << last_msg_.signature[8]; - EXPECT_EQ(last_msg_.signature[9], 9) - << "incorrect value for last_msg_.signature[9], expected 9, is " - << last_msg_.signature[9]; - EXPECT_EQ(last_msg_.signature[10], 10) - << "incorrect value for last_msg_.signature[10], expected 10, is " - << last_msg_.signature[10]; - EXPECT_EQ(last_msg_.signature[11], 11) - << "incorrect value for last_msg_.signature[11], expected 11, is " - << last_msg_.signature[11]; - EXPECT_EQ(last_msg_.signature[12], 12) - << "incorrect value for last_msg_.signature[12], expected 12, is " - << last_msg_.signature[12]; - EXPECT_EQ(last_msg_.signature[13], 13) - << "incorrect value for last_msg_.signature[13], expected 13, is " - << last_msg_.signature[13]; - EXPECT_EQ(last_msg_.signature[14], 14) - << "incorrect value for last_msg_.signature[14], expected 14, is " - << last_msg_.signature[14]; - EXPECT_EQ(last_msg_.signature[15], 15) - << "incorrect value for last_msg_.signature[15], expected 15, is " - << last_msg_.signature[15]; - EXPECT_EQ(last_msg_.signature[16], 16) - << "incorrect value for last_msg_.signature[16], expected 16, is " - << last_msg_.signature[16]; - EXPECT_EQ(last_msg_.signature[17], 17) - << "incorrect value for last_msg_.signature[17], expected 17, is " - << last_msg_.signature[17]; - EXPECT_EQ(last_msg_.signature[18], 18) - << "incorrect value for last_msg_.signature[18], expected 18, is " - << last_msg_.signature[18]; - EXPECT_EQ(last_msg_.signature[19], 19) - << "incorrect value for last_msg_.signature[19], expected 19, is " - << last_msg_.signature[19]; - EXPECT_EQ(last_msg_.signature[20], 20) - << "incorrect value for last_msg_.signature[20], expected 20, is " - << last_msg_.signature[20]; - EXPECT_EQ(last_msg_.signature[21], 21) - << "incorrect value for last_msg_.signature[21], expected 21, is " - << last_msg_.signature[21]; - EXPECT_EQ(last_msg_.signature[22], 22) - << "incorrect value for last_msg_.signature[22], expected 22, is " - << last_msg_.signature[22]; - EXPECT_EQ(last_msg_.signature[23], 23) - << "incorrect value for last_msg_.signature[23], expected 23, is " - << last_msg_.signature[23]; - EXPECT_EQ(last_msg_.signature[24], 24) - << "incorrect value for last_msg_.signature[24], expected 24, is " - << last_msg_.signature[24]; - EXPECT_EQ(last_msg_.signature[25], 25) - << "incorrect value for last_msg_.signature[25], expected 25, is " - << last_msg_.signature[25]; - EXPECT_EQ(last_msg_.signature[26], 26) - << "incorrect value for last_msg_.signature[26], expected 26, is " - << last_msg_.signature[26]; - EXPECT_EQ(last_msg_.signature[27], 27) - << "incorrect value for last_msg_.signature[27], expected 27, is " - << last_msg_.signature[27]; - EXPECT_EQ(last_msg_.signature[28], 28) - << "incorrect value for last_msg_.signature[28], expected 28, is " - << last_msg_.signature[28]; - EXPECT_EQ(last_msg_.signature[29], 29) - << "incorrect value for last_msg_.signature[29], expected 29, is " - << last_msg_.signature[29]; - EXPECT_EQ(last_msg_.signature[30], 30) - << "incorrect value for last_msg_.signature[30], expected 30, is " - << last_msg_.signature[30]; - EXPECT_EQ(last_msg_.signature[31], 31) - << "incorrect value for last_msg_.signature[31], expected 31, is " - << last_msg_.signature[31]; - EXPECT_EQ(last_msg_.signature[32], 32) - << "incorrect value for last_msg_.signature[32], expected 32, is " - << last_msg_.signature[32]; - EXPECT_EQ(last_msg_.signature[33], 33) - << "incorrect value for last_msg_.signature[33], expected 33, is " - << last_msg_.signature[33]; - EXPECT_EQ(last_msg_.signature[34], 34) - << "incorrect value for last_msg_.signature[34], expected 34, is " - << last_msg_.signature[34]; - EXPECT_EQ(last_msg_.signature[35], 35) - << "incorrect value for last_msg_.signature[35], expected 35, is " - << last_msg_.signature[35]; - EXPECT_EQ(last_msg_.signature[36], 36) - << "incorrect value for last_msg_.signature[36], expected 36, is " - << last_msg_.signature[36]; - EXPECT_EQ(last_msg_.signature[37], 37) - << "incorrect value for last_msg_.signature[37], expected 37, is " - << last_msg_.signature[37]; - EXPECT_EQ(last_msg_.signature[38], 38) - << "incorrect value for last_msg_.signature[38], expected 38, is " - << last_msg_.signature[38]; - EXPECT_EQ(last_msg_.signature[39], 39) - << "incorrect value for last_msg_.signature[39], expected 39, is " - << last_msg_.signature[39]; - EXPECT_EQ(last_msg_.signature[40], 40) - << "incorrect value for last_msg_.signature[40], expected 40, is " - << last_msg_.signature[40]; - EXPECT_EQ(last_msg_.signature[41], 41) - << "incorrect value for last_msg_.signature[41], expected 41, is " - << last_msg_.signature[41]; - EXPECT_EQ(last_msg_.signature[42], 42) - << "incorrect value for last_msg_.signature[42], expected 42, is " - << last_msg_.signature[42]; - EXPECT_EQ(last_msg_.signature[43], 43) - << "incorrect value for last_msg_.signature[43], expected 43, is " - << last_msg_.signature[43]; - EXPECT_EQ(last_msg_.signature[44], 44) - << "incorrect value for last_msg_.signature[44], expected 44, is " - << last_msg_.signature[44]; - EXPECT_EQ(last_msg_.signature[45], 45) - << "incorrect value for last_msg_.signature[45], expected 45, is " - << last_msg_.signature[45]; - EXPECT_EQ(last_msg_.signature[46], 46) - << "incorrect value for last_msg_.signature[46], expected 46, is " - << last_msg_.signature[46]; - EXPECT_EQ(last_msg_.signature[47], 47) - << "incorrect value for last_msg_.signature[47], expected 47, is " - << last_msg_.signature[47]; - EXPECT_EQ(last_msg_.signature[48], 48) - << "incorrect value for last_msg_.signature[48], expected 48, is " - << last_msg_.signature[48]; - EXPECT_EQ(last_msg_.signature[49], 49) - << "incorrect value for last_msg_.signature[49], expected 49, is " - << last_msg_.signature[49]; - EXPECT_EQ(last_msg_.signature[50], 50) - << "incorrect value for last_msg_.signature[50], expected 50, is " - << last_msg_.signature[50]; - EXPECT_EQ(last_msg_.signature[51], 51) - << "incorrect value for last_msg_.signature[51], expected 51, is " - << last_msg_.signature[51]; - EXPECT_EQ(last_msg_.signature[52], 52) - << "incorrect value for last_msg_.signature[52], expected 52, is " - << last_msg_.signature[52]; - EXPECT_EQ(last_msg_.signature[53], 53) - << "incorrect value for last_msg_.signature[53], expected 53, is " - << last_msg_.signature[53]; - EXPECT_EQ(last_msg_.signature[54], 54) - << "incorrect value for last_msg_.signature[54], expected 54, is " - << last_msg_.signature[54]; - EXPECT_EQ(last_msg_.signature[55], 55) - << "incorrect value for last_msg_.signature[55], expected 55, is " - << last_msg_.signature[55]; - EXPECT_EQ(last_msg_.signature[56], 56) - << "incorrect value for last_msg_.signature[56], expected 56, is " - << last_msg_.signature[56]; - EXPECT_EQ(last_msg_.signature[57], 57) - << "incorrect value for last_msg_.signature[57], expected 57, is " - << last_msg_.signature[57]; - EXPECT_EQ(last_msg_.signature[58], 58) - << "incorrect value for last_msg_.signature[58], expected 58, is " - << last_msg_.signature[58]; - EXPECT_EQ(last_msg_.signature[59], 59) - << "incorrect value for last_msg_.signature[59], expected 59, is " - << last_msg_.signature[59]; - EXPECT_EQ(last_msg_.signature[60], 60) - << "incorrect value for last_msg_.signature[60], expected 60, is " - << last_msg_.signature[60]; - EXPECT_EQ(last_msg_.signature[61], 61) - << "incorrect value for last_msg_.signature[61], expected 61, is " - << last_msg_.signature[61]; - EXPECT_EQ(last_msg_.signature[62], 62) - << "incorrect value for last_msg_.signature[62], expected 62, is " - << last_msg_.signature[62]; - EXPECT_EQ(last_msg_.signature[63], 63) - << "incorrect value for last_msg_.signature[63], expected 63, is " - << last_msg_.signature[63]; - EXPECT_EQ(last_msg_.signed_messages[0], 5000) - << "incorrect value for last_msg_.signed_messages[0], expected 5000, is " - << last_msg_.signed_messages[0]; - EXPECT_EQ(last_msg_.signed_messages[1], 5234) - << "incorrect value for last_msg_.signed_messages[1], expected 5234, is " - << last_msg_.signed_messages[1]; - EXPECT_EQ(last_msg_.signed_messages[2], 5468) - << "incorrect value for last_msg_.signed_messages[2], expected 5468, is " - << last_msg_.signed_messages[2]; - EXPECT_EQ(last_msg_.signed_messages[3], 5702) - << "incorrect value for last_msg_.signed_messages[3], expected 5702, is " - << last_msg_.signed_messages[3]; - EXPECT_EQ(last_msg_.signed_messages[4], 5936) - << "incorrect value for last_msg_.signed_messages[4], expected 5936, is " - << last_msg_.signed_messages[4]; - EXPECT_EQ(last_msg_.signed_messages[5], 6170) - << "incorrect value for last_msg_.signed_messages[5], expected 6170, is " - << last_msg_.signed_messages[5]; - EXPECT_EQ(last_msg_.signed_messages[6], 6404) - << "incorrect value for last_msg_.signed_messages[6], expected 6404, is " - << last_msg_.signed_messages[6]; - EXPECT_EQ(last_msg_.signed_messages[7], 6638) - << "incorrect value for last_msg_.signed_messages[7], expected 6638, is " - << last_msg_.signed_messages[7]; - EXPECT_EQ(last_msg_.signed_messages[8], 6872) - << "incorrect value for last_msg_.signed_messages[8], expected 6872, is " - << last_msg_.signed_messages[8]; - EXPECT_EQ(last_msg_.signed_messages[9], 7106) - << "incorrect value for last_msg_.signed_messages[9], expected 7106, is " - << last_msg_.signed_messages[9]; - EXPECT_EQ(last_msg_.signed_messages[10], 7340) - << "incorrect value for last_msg_.signed_messages[10], expected 7340, is " - << last_msg_.signed_messages[10]; - EXPECT_EQ(last_msg_.signed_messages[11], 7574) - << "incorrect value for last_msg_.signed_messages[11], expected 7574, is " - << last_msg_.signed_messages[11]; - EXPECT_EQ(last_msg_.signed_messages[12], 7808) - << "incorrect value for last_msg_.signed_messages[12], expected 7808, is " - << last_msg_.signed_messages[12]; - EXPECT_EQ(last_msg_.signed_messages[13], 8042) - << "incorrect value for last_msg_.signed_messages[13], expected 8042, is " - << last_msg_.signed_messages[13]; - EXPECT_EQ(last_msg_.signed_messages[14], 8276) - << "incorrect value for last_msg_.signed_messages[14], expected 8276, is " - << last_msg_.signed_messages[14]; - EXPECT_EQ(last_msg_.signed_messages[15], 8510) - << "incorrect value for last_msg_.signed_messages[15], expected 8510, is " - << last_msg_.signed_messages[15]; - EXPECT_EQ(last_msg_.signed_messages[16], 8744) - << "incorrect value for last_msg_.signed_messages[16], expected 8744, is " - << last_msg_.signed_messages[16]; - EXPECT_EQ(last_msg_.signed_messages[17], 8978) - << "incorrect value for last_msg_.signed_messages[17], expected 8978, is " - << last_msg_.signed_messages[17]; - EXPECT_EQ(last_msg_.signed_messages[18], 9212) - << "incorrect value for last_msg_.signed_messages[18], expected 9212, is " - << last_msg_.signed_messages[18]; - EXPECT_EQ(last_msg_.signed_messages[19], 9446) - << "incorrect value for last_msg_.signed_messages[19], expected 9446, is " - << last_msg_.signed_messages[19]; - EXPECT_EQ(last_msg_.signed_messages[20], 9680) - << "incorrect value for last_msg_.signed_messages[20], expected 9680, is " - << last_msg_.signed_messages[20]; - EXPECT_EQ(last_msg_.signed_messages[21], 9914) - << "incorrect value for last_msg_.signed_messages[21], expected 9914, is " - << last_msg_.signed_messages[21]; - EXPECT_EQ(last_msg_.signed_messages[22], 10148) - << "incorrect value for last_msg_.signed_messages[22], expected 10148, " - "is " - << last_msg_.signed_messages[22]; - EXPECT_EQ(last_msg_.signed_messages[23], 10382) - << "incorrect value for last_msg_.signed_messages[23], expected 10382, " - "is " - << last_msg_.signed_messages[23]; - EXPECT_EQ(last_msg_.signed_messages[24], 10616) - << "incorrect value for last_msg_.signed_messages[24], expected 10616, " - "is " - << last_msg_.signed_messages[24]; - EXPECT_EQ(last_msg_.stream_counter, 1) - << "incorrect value for last_msg_.stream_counter, expected 1, is " - << last_msg_.stream_counter; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgEd25519SignatureDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_signing_MsgEd25519SignatureDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgEd25519SignatureDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds.cc index 0547f18f26..615798c48a 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds.cc @@ -16,212 +16,823 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0 + : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0() { + assign(test_msg_.const_id, 1); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.sol_id, 14); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 1); + assign(test_msg_.n_sats_signals, 3); + + assign(test_msg_.satellites_signals[0].code_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[0].code_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[0].phase_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[0].phase_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[0].sat_id, 0); + assign(test_msg_.satellites_signals[0].signal_id, 3); + + assign(test_msg_.satellites_signals[1].code_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[1].code_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[1].phase_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[1].phase_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[1].sat_id, 1); + assign(test_msg_.satellites_signals[1].signal_id, 3); + + assign(test_msg_.satellites_signals[2].code_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[2].code_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[2].phase_bias_bound_mu, 39); + assign(test_msg_.satellites_signals[2].phase_bias_bound_sig, 1); + assign(test_msg_.satellites_signals[2].sat_id, 1); + assign(test_msg_.satellites_signals[2].signal_id, 1); + assign(test_msg_.ssr_iod, 15); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_code_phase_biases_bounds_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_code_phase_biases_bounds_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_code_phase_biases_bounds_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrCodePhaseBiasesBounds, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_code_phase_biases_bounds_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrCodePhaseBiasesBounds); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_code_phase_biases_bounds, + sizeof(msg->ssr_code_phase_biases_bounds)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_code_phase_biases_bounds_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_code_phase_biases_bounds, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrCodePhaseBiasesBounds); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x7117; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 31; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_code_phase_biases_bounds_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_code_phase_biases_bounds_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_code_phase_biases_bounds_t &lesser, + const sbp_msg_ssr_code_phase_biases_bounds_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_code_phase_biases_bounds_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_code_phase_biases_bounds_cmp(&greater, &lesser), 0); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrCodePhaseBiasesBounds, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrCodePhaseBiasesBounds, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrCodePhaseBiasesBounds, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrCodePhaseBiasesBounds, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_code_phase_biases_bounds_t test_msg_{}; + uint8_t encoded_frame_[31 + 8] = { 85, 236, 5, 66, 0, 31, 180, 0, 0, 0, 3, 0, 1, 2, 1, 14, 15, 1, 3, 0, 3, 39, 1, 39, 1, 1, 3, 39, 1, 39, 1, 1, 1, 39, 1, 39, 1, 23, 113, }; + uint8_t encoded_payload_[31] = { + 180, 0, 0, 0, 3, 0, 1, 2, 1, 14, 15, 1, 3, 0, 3, 39, + 1, 39, 1, 1, 3, 39, 1, 39, 1, 1, 1, 39, 1, 39, 1, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrCodePhaseBiasesBounds, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrCodePhaseBiasesBounds, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_encode( + &buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + for (uint8_t i = 0; i < 31; i++) { + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_code_phase_biases_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrCodePhaseBiasesBounds, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_code_phase_biases_bounds_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_code_phase_biases_bounds_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_code_phase_biases_bounds_t t{}; + return sbp_msg_ssr_code_phase_biases_bounds_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_code_phase_biases_bounds_t t{}; + t.n_sats_signals = 1; + return sbp_msg_ssr_code_phase_biases_bounds_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_ssr_code_phase_biases_bounds_t test_msg{}; - test_msg.const_id = 1; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 2; - test_msg.header.sol_id = 14; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 1; - test_msg.n_sats_signals = 3; - - test_msg.satellites_signals[0].code_bias_bound_mu = 39; - test_msg.satellites_signals[0].code_bias_bound_sig = 1; - test_msg.satellites_signals[0].phase_bias_bound_mu = 39; - test_msg.satellites_signals[0].phase_bias_bound_sig = 1; - test_msg.satellites_signals[0].sat_id = 0; - test_msg.satellites_signals[0].signal_id = 3; - - test_msg.satellites_signals[1].code_bias_bound_mu = 39; - test_msg.satellites_signals[1].code_bias_bound_sig = 1; - test_msg.satellites_signals[1].phase_bias_bound_mu = 39; - test_msg.satellites_signals[1].phase_bias_bound_sig = 1; - test_msg.satellites_signals[1].sat_id = 1; - test_msg.satellites_signals[1].signal_id = 3; - - test_msg.satellites_signals[2].code_bias_bound_mu = 39; - test_msg.satellites_signals[2].code_bias_bound_sig = 1; - test_msg.satellites_signals[2].phase_bias_bound_mu = 39; - test_msg.satellites_signals[2].phase_bias_bound_sig = 1; - test_msg.satellites_signals[2].sat_id = 1; - test_msg.satellites_signals[2].signal_id = 1; - test_msg.ssr_iod = 15; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.const_id, 1) - << "incorrect value for last_msg_.const_id, expected 1, is " - << last_msg_.const_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 14) - << "incorrect value for last_msg_.header.sol_id, expected 14, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 1) - << "incorrect value for last_msg_.header.update_interval, expected 1, is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.n_sats_signals, 3) - << "incorrect value for last_msg_.n_sats_signals, expected 3, is " - << last_msg_.n_sats_signals; - EXPECT_EQ(last_msg_.satellites_signals[0].code_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[0].code_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[0].code_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[0].code_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[0].code_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[0].code_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[0].phase_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[0].phase_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[0].phase_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[0].phase_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[0].phase_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[0].phase_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[0].sat_id, 0) - << "incorrect value for last_msg_.satellites_signals[0].sat_id, expected " - "0, is " - << last_msg_.satellites_signals[0].sat_id; - EXPECT_EQ(last_msg_.satellites_signals[0].signal_id, 3) - << "incorrect value for last_msg_.satellites_signals[0].signal_id, " - "expected 3, is " - << last_msg_.satellites_signals[0].signal_id; - EXPECT_EQ(last_msg_.satellites_signals[1].code_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[1].code_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[1].code_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[1].code_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[1].code_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[1].code_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[1].phase_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[1].phase_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[1].phase_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[1].phase_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[1].phase_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[1].phase_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[1].sat_id, 1) - << "incorrect value for last_msg_.satellites_signals[1].sat_id, expected " - "1, is " - << last_msg_.satellites_signals[1].sat_id; - EXPECT_EQ(last_msg_.satellites_signals[1].signal_id, 3) - << "incorrect value for last_msg_.satellites_signals[1].signal_id, " - "expected 3, is " - << last_msg_.satellites_signals[1].signal_id; - EXPECT_EQ(last_msg_.satellites_signals[2].code_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[2].code_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[2].code_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[2].code_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[2].code_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[2].code_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[2].phase_bias_bound_mu, 39) - << "incorrect value for " - "last_msg_.satellites_signals[2].phase_bias_bound_mu, expected 39, is " - << last_msg_.satellites_signals[2].phase_bias_bound_mu; - EXPECT_EQ(last_msg_.satellites_signals[2].phase_bias_bound_sig, 1) - << "incorrect value for " - "last_msg_.satellites_signals[2].phase_bias_bound_sig, expected 1, is " - << last_msg_.satellites_signals[2].phase_bias_bound_sig; - EXPECT_EQ(last_msg_.satellites_signals[2].sat_id, 1) - << "incorrect value for last_msg_.satellites_signals[2].sat_id, expected " - "1, is " - << last_msg_.satellites_signals[2].sat_id; - EXPECT_EQ(last_msg_.satellites_signals[2].signal_id, 1) - << "incorrect value for last_msg_.satellites_signals[2].signal_id, " - "expected 1, is " - << last_msg_.satellites_signals[2].signal_id; - EXPECT_EQ(last_msg_.ssr_iod, 15) - << "incorrect value for last_msg_.ssr_iod, expected 15, is " - << last_msg_.ssr_iod; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_code_phase_biases_bounds_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrCodePhaseBiasesBounds, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.const_id, greater.const_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats_signals, greater.n_sats_signals); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].code_bias_bound_mu, + greater.satellites_signals[0].code_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].code_bias_bound_sig, + greater.satellites_signals[0].code_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].phase_bias_bound_mu, + greater.satellites_signals[0].phase_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].phase_bias_bound_sig, + greater.satellites_signals[0].phase_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].sat_id, + greater.satellites_signals[0].sat_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[0].signal_id, + greater.satellites_signals[0].signal_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].code_bias_bound_mu, + greater.satellites_signals[1].code_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].code_bias_bound_sig, + greater.satellites_signals[1].code_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].phase_bias_bound_mu, + greater.satellites_signals[1].phase_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].phase_bias_bound_sig, + greater.satellites_signals[1].phase_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].sat_id, + greater.satellites_signals[1].sat_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[1].signal_id, + greater.satellites_signals[1].signal_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].code_bias_bound_mu, + greater.satellites_signals[2].code_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].code_bias_bound_sig, + greater.satellites_signals[2].code_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].phase_bias_bound_mu, + greater.satellites_signals[2].phase_bias_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].phase_bias_bound_sig, + greater.satellites_signals[2].phase_bias_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].sat_id, + greater.satellites_signals[2].sat_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.satellites_signals[2].signal_id, + greater.satellites_signals[2].signal_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_code_phase_biases_bounds_t lesser = info.test_msg; + sbp_msg_ssr_code_phase_biases_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod, greater.ssr_iod); + comparison_tests(lesser, greater); + } } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrCodePhaseBiasesBounds); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_CODE_PHASE_BIASES_BOUNDS"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_code_phase_biases_bounds_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_code_phase_biases_bounds_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_code_phase_biases_bounds, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_code_phase_biases_bounds, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_code_phase_biases_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrCodePhaseBiasesBounds, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrCodePhaseBiasesBounds0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrCodePhaseBiasesBounds, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds.cc index 280a6059de..2423da1212 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds.cc @@ -16,413 +16,1615 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0 + : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0() { + assign(test_msg_.grid_point_id, 1000); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 0); + assign(test_msg_.header.sol_id, 0); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 10); + assign(test_msg_.n_sats, 2); + assign(test_msg_.ssr_iod_atmo, 15); + + assign(test_msg_.stec_sat_list[0].stec_bound_mu, 18); + assign(test_msg_.stec_sat_list[0].stec_bound_mu_dot, 20); + assign(test_msg_.stec_sat_list[0].stec_bound_sig, 19); + assign(test_msg_.stec_sat_list[0].stec_bound_sig_dot, 21); + assign(test_msg_.stec_sat_list[0].stec_residual.residual, 16); + assign(test_msg_.stec_sat_list[0].stec_residual.stddev, 17); + assign(test_msg_.stec_sat_list[0].stec_residual.sv_id.constellation, 10); + assign(test_msg_.stec_sat_list[0].stec_residual.sv_id.satId, 5); + + assign(test_msg_.stec_sat_list[1].stec_bound_mu, 24); + assign(test_msg_.stec_sat_list[1].stec_bound_mu_dot, 26); + assign(test_msg_.stec_sat_list[1].stec_bound_sig, 25); + assign(test_msg_.stec_sat_list[1].stec_bound_sig_dot, 27); + assign(test_msg_.stec_sat_list[1].stec_residual.residual, 22); + assign(test_msg_.stec_sat_list[1].stec_residual.stddev, 23); + assign(test_msg_.stec_sat_list[1].stec_residual.sv_id.constellation, 10); + assign(test_msg_.stec_sat_list[1].stec_residual.sv_id.satId, 6); + assign(test_msg_.tile_id, 10); + assign(test_msg_.tile_set_id, 1); + assign(test_msg_.tropo_delay_correction.hydro, 500); + assign(test_msg_.tropo_delay_correction.stddev, 200); + assign(test_msg_.tropo_delay_correction.wet, 100); + assign(test_msg_.tropo_qi, 39); + assign(test_msg_.tropo_v_hydro_bound_mu, 150); + assign(test_msg_.tropo_v_hydro_bound_sig, 100); + assign(test_msg_.tropo_v_wet_bound_mu, 150); + assign(test_msg_.tropo_v_wet_bound_sig, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_gridded_correction_bounds_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_gridded_correction_bounds_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_gridded_correction_bounds_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrGriddedCorrectionBounds, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_gridded_correction_bounds_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrGriddedCorrectionBounds); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_gridded_correction_bounds, + sizeof(msg->ssr_gridded_correction_bounds)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_gridded_correction_bounds_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_gridded_correction_bounds, &test_msg_, + sizeof(test_msg_)); + info.msg_type = + static_cast(SbpMsgSsrGriddedCorrectionBounds); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xB6EC; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 45; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_gridded_correction_bounds_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_gridded_correction_bounds_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests( + const sbp_msg_ssr_gridded_correction_bounds_t &lesser, + const sbp_msg_ssr_gridded_correction_bounds_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_gridded_correction_bounds_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_gridded_correction_bounds_cmp(&greater, &lesser), 0); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, + &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, + &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_gridded_correction_bounds_t test_msg_{}; + uint8_t encoded_frame_[45 + 8] = { 85, 254, 5, 66, 0, 45, 180, 0, 0, 0, 3, 0, 1, 0, 10, 0, 15, 1, 0, 10, 0, 39, 232, 3, 244, 1, 100, 200, 150, 100, 150, 100, 2, 5, 10, 16, 0, 17, 18, 19, 20, 21, 6, 10, 22, 0, 23, 24, 25, 26, 27, 236, 182, }; + uint8_t encoded_payload_[45] = { + 180, 0, 0, 0, 3, 0, 1, 0, 10, 0, 15, 1, 0, 10, 0, + 39, 232, 3, 244, 1, 100, 200, 150, 100, 150, 100, 2, 5, 10, 16, + 0, 17, 18, 19, 20, 21, 6, 10, 22, 0, 23, 24, 25, 26, 27, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[45]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 45); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 45), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 45); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 45), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[45]; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode( + &buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 45), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[45]; + + for (uint8_t i = 0; i < 45; i++) { + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 45); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrGriddedCorrectionBounds, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 45); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_gridded_correction_bounds_t t{}; + return sbp_msg_ssr_gridded_correction_bounds_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_gridded_correction_bounds_t t{}; + t.n_sats = 1; + return sbp_msg_ssr_gridded_correction_bounds_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrGriddedCorrectionBounds, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.grid_point_id, greater.grid_point_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod_atmo, greater.ssr_iod_atmo); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_bound_mu, + greater.stec_sat_list[0].stec_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_bound_mu_dot, + greater.stec_sat_list[0].stec_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_bound_sig, + greater.stec_sat_list[0].stec_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_bound_sig_dot, + greater.stec_sat_list[0].stec_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_residual.residual, + greater.stec_sat_list[0].stec_residual.residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_residual.stddev, + greater.stec_sat_list[0].stec_residual.stddev); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater( + lesser.stec_sat_list[0].stec_residual.sv_id.constellation, + greater.stec_sat_list[0].stec_residual.sv_id.constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_residual.sv_id.satId, + greater.stec_sat_list[0].stec_residual.sv_id.satId); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_bound_mu, + greater.stec_sat_list[1].stec_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_bound_mu_dot, + greater.stec_sat_list[1].stec_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_bound_sig, + greater.stec_sat_list[1].stec_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_bound_sig_dot, + greater.stec_sat_list[1].stec_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_residual.residual, + greater.stec_sat_list[1].stec_residual.residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_residual.stddev, + greater.stec_sat_list[1].stec_residual.stddev); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater( + lesser.stec_sat_list[1].stec_residual.sv_id.constellation, + greater.stec_sat_list[1].stec_residual.sv_id.constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_residual.sv_id.satId, + greater.stec_sat_list[1].stec_residual.sv_id.satId); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.hydro, + greater.tropo_delay_correction.hydro); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.stddev, + greater.tropo_delay_correction.stddev); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.wet, + greater.tropo_delay_correction.wet); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_qi, greater.tropo_qi); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_hydro_bound_mu, + greater.tropo_v_hydro_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_hydro_bound_sig, + greater.tropo_v_hydro_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_wet_bound_mu, + greater.tropo_v_wet_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_wet_bound_sig, + greater.tropo_v_wet_bound_sig); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrGriddedCorrectionBounds); + EXPECT_STREQ( + sbp::MessageTraits::name, + "MSG_SSR_GRIDDED_CORRECTION_BOUNDS"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_gridded_correction_bounds_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_gridded_correction_bounds_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_gridded_correction_bounds, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_gridded_correction_bounds, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[45]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 45); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 45), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 45); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - sbp_msg_ssr_gridded_correction_bounds_t test_msg{}; - test_msg.grid_point_id = 1000; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 0; - test_msg.header.sol_id = 0; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 10; - test_msg.n_sats = 2; - test_msg.ssr_iod_atmo = 15; - - test_msg.stec_sat_list[0].stec_bound_mu = 18; - test_msg.stec_sat_list[0].stec_bound_mu_dot = 20; - test_msg.stec_sat_list[0].stec_bound_sig = 19; - test_msg.stec_sat_list[0].stec_bound_sig_dot = 21; - test_msg.stec_sat_list[0].stec_residual.residual = 16; - test_msg.stec_sat_list[0].stec_residual.stddev = 17; - test_msg.stec_sat_list[0].stec_residual.sv_id.constellation = 10; - test_msg.stec_sat_list[0].stec_residual.sv_id.satId = 5; - - test_msg.stec_sat_list[1].stec_bound_mu = 24; - test_msg.stec_sat_list[1].stec_bound_mu_dot = 26; - test_msg.stec_sat_list[1].stec_bound_sig = 25; - test_msg.stec_sat_list[1].stec_bound_sig_dot = 27; - test_msg.stec_sat_list[1].stec_residual.residual = 22; - test_msg.stec_sat_list[1].stec_residual.stddev = 23; - test_msg.stec_sat_list[1].stec_residual.sv_id.constellation = 10; - test_msg.stec_sat_list[1].stec_residual.sv_id.satId = 6; - test_msg.tile_id = 10; - test_msg.tile_set_id = 1; - test_msg.tropo_delay_correction.hydro = 500; - test_msg.tropo_delay_correction.stddev = 200; - test_msg.tropo_delay_correction.wet = 100; - test_msg.tropo_qi = 39; - test_msg.tropo_v_hydro_bound_mu = 150; - test_msg.tropo_v_hydro_bound_sig = 100; - test_msg.tropo_v_wet_bound_mu = 150; - test_msg.tropo_v_wet_bound_sig = 100; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.grid_point_id, 1000) - << "incorrect value for last_msg_.grid_point_id, expected 1000, is " - << last_msg_.grid_point_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 0) - << "incorrect value for last_msg_.header.seq_num, expected 0, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 0) - << "incorrect value for last_msg_.header.sol_id, expected 0, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 10) - << "incorrect value for last_msg_.header.update_interval, expected 10, " - "is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.n_sats, 2) - << "incorrect value for last_msg_.n_sats, expected 2, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.ssr_iod_atmo, 15) - << "incorrect value for last_msg_.ssr_iod_atmo, expected 15, is " - << last_msg_.ssr_iod_atmo; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_bound_mu, 18) - << "incorrect value for last_msg_.stec_sat_list[0].stec_bound_mu, " - "expected 18, is " - << last_msg_.stec_sat_list[0].stec_bound_mu; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_bound_mu_dot, 20) - << "incorrect value for last_msg_.stec_sat_list[0].stec_bound_mu_dot, " - "expected 20, is " - << last_msg_.stec_sat_list[0].stec_bound_mu_dot; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_bound_sig, 19) - << "incorrect value for last_msg_.stec_sat_list[0].stec_bound_sig, " - "expected 19, is " - << last_msg_.stec_sat_list[0].stec_bound_sig; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_bound_sig_dot, 21) - << "incorrect value for last_msg_.stec_sat_list[0].stec_bound_sig_dot, " - "expected 21, is " - << last_msg_.stec_sat_list[0].stec_bound_sig_dot; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_residual.residual, 16) - << "incorrect value for " - "last_msg_.stec_sat_list[0].stec_residual.residual, expected 16, is " - << last_msg_.stec_sat_list[0].stec_residual.residual; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_residual.stddev, 17) - << "incorrect value for last_msg_.stec_sat_list[0].stec_residual.stddev, " - "expected 17, is " - << last_msg_.stec_sat_list[0].stec_residual.stddev; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_residual.sv_id.constellation, 10) - << "incorrect value for " - "last_msg_.stec_sat_list[0].stec_residual.sv_id.constellation, " - "expected 10, is " - << last_msg_.stec_sat_list[0].stec_residual.sv_id.constellation; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_residual.sv_id.satId, 5) - << "incorrect value for " - "last_msg_.stec_sat_list[0].stec_residual.sv_id.satId, expected 5, is " - << last_msg_.stec_sat_list[0].stec_residual.sv_id.satId; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_bound_mu, 24) - << "incorrect value for last_msg_.stec_sat_list[1].stec_bound_mu, " - "expected 24, is " - << last_msg_.stec_sat_list[1].stec_bound_mu; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_bound_mu_dot, 26) - << "incorrect value for last_msg_.stec_sat_list[1].stec_bound_mu_dot, " - "expected 26, is " - << last_msg_.stec_sat_list[1].stec_bound_mu_dot; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_bound_sig, 25) - << "incorrect value for last_msg_.stec_sat_list[1].stec_bound_sig, " - "expected 25, is " - << last_msg_.stec_sat_list[1].stec_bound_sig; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_bound_sig_dot, 27) - << "incorrect value for last_msg_.stec_sat_list[1].stec_bound_sig_dot, " - "expected 27, is " - << last_msg_.stec_sat_list[1].stec_bound_sig_dot; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_residual.residual, 22) - << "incorrect value for " - "last_msg_.stec_sat_list[1].stec_residual.residual, expected 22, is " - << last_msg_.stec_sat_list[1].stec_residual.residual; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_residual.stddev, 23) - << "incorrect value for last_msg_.stec_sat_list[1].stec_residual.stddev, " - "expected 23, is " - << last_msg_.stec_sat_list[1].stec_residual.stddev; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_residual.sv_id.constellation, 10) - << "incorrect value for " - "last_msg_.stec_sat_list[1].stec_residual.sv_id.constellation, " - "expected 10, is " - << last_msg_.stec_sat_list[1].stec_residual.sv_id.constellation; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_residual.sv_id.satId, 6) - << "incorrect value for " - "last_msg_.stec_sat_list[1].stec_residual.sv_id.satId, expected 6, is " - << last_msg_.stec_sat_list[1].stec_residual.sv_id.satId; - EXPECT_EQ(last_msg_.tile_id, 10) - << "incorrect value for last_msg_.tile_id, expected 10, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 1) - << "incorrect value for last_msg_.tile_set_id, expected 1, is " - << last_msg_.tile_set_id; - EXPECT_EQ(last_msg_.tropo_delay_correction.hydro, 500) - << "incorrect value for last_msg_.tropo_delay_correction.hydro, expected " - "500, is " - << last_msg_.tropo_delay_correction.hydro; - EXPECT_EQ(last_msg_.tropo_delay_correction.stddev, 200) - << "incorrect value for last_msg_.tropo_delay_correction.stddev, " - "expected 200, is " - << last_msg_.tropo_delay_correction.stddev; - EXPECT_EQ(last_msg_.tropo_delay_correction.wet, 100) - << "incorrect value for last_msg_.tropo_delay_correction.wet, expected " - "100, is " - << last_msg_.tropo_delay_correction.wet; - EXPECT_EQ(last_msg_.tropo_qi, 39) - << "incorrect value for last_msg_.tropo_qi, expected 39, is " - << last_msg_.tropo_qi; - EXPECT_EQ(last_msg_.tropo_v_hydro_bound_mu, 150) - << "incorrect value for last_msg_.tropo_v_hydro_bound_mu, expected 150, " - "is " - << last_msg_.tropo_v_hydro_bound_mu; - EXPECT_EQ(last_msg_.tropo_v_hydro_bound_sig, 100) - << "incorrect value for last_msg_.tropo_v_hydro_bound_sig, expected 100, " - "is " - << last_msg_.tropo_v_hydro_bound_sig; - EXPECT_EQ(last_msg_.tropo_v_wet_bound_mu, 150) - << "incorrect value for last_msg_.tropo_v_wet_bound_mu, expected 150, is " - << last_msg_.tropo_v_wet_bound_mu; - EXPECT_EQ(last_msg_.tropo_v_wet_bound_sig, 100) - << "incorrect value for last_msg_.tropo_v_wet_bound_sig, expected 100, " - "is " - << last_msg_.tropo_v_wet_bound_sig; -} -class Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrGriddedCorrectionBounds, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1 + : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1() { + assign(test_msg_.grid_point_id, 1000); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 0); + assign(test_msg_.header.sol_id, 0); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 10); + assign(test_msg_.n_sats, 0); + assign(test_msg_.ssr_iod_atmo, 15); + assign(test_msg_.tile_id, 10); + assign(test_msg_.tile_set_id, 1); + assign(test_msg_.tropo_delay_correction.hydro, 500); + assign(test_msg_.tropo_delay_correction.stddev, 200); + assign(test_msg_.tropo_delay_correction.wet, 100); + assign(test_msg_.tropo_qi, 39); + assign(test_msg_.tropo_v_hydro_bound_mu, 150); + assign(test_msg_.tropo_v_hydro_bound_sig, 100); + assign(test_msg_.tropo_v_wet_bound_mu, 150); + assign(test_msg_.tropo_v_wet_bound_sig, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_gridded_correction_bounds_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_gridded_correction_bounds_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_gridded_correction_bounds_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrGriddedCorrectionBounds, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_gridded_correction_bounds_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrGriddedCorrectionBounds); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_gridded_correction_bounds, + sizeof(msg->ssr_gridded_correction_bounds)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_gridded_correction_bounds_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_gridded_correction_bounds, &test_msg_, + sizeof(test_msg_)); + info.msg_type = + static_cast(SbpMsgSsrGriddedCorrectionBounds); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x249B; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 27; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_gridded_correction_bounds_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_gridded_correction_bounds_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests( + const sbp_msg_ssr_gridded_correction_bounds_t &lesser, + const sbp_msg_ssr_gridded_correction_bounds_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_gridded_correction_bounds_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_gridded_correction_bounds_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, + &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrGriddedCorrectionBounds, + &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ssr_gridded_correction_bounds_t test_msg_{}; + uint8_t encoded_frame_[27 + 8] = { 85, 254, 5, 66, 0, 27, 180, 0, 0, 0, 3, 0, 1, 0, 10, 0, 15, 1, 0, 10, 0, 39, 232, 3, 244, 1, 100, 200, 150, 100, 150, 100, 0, 155, 36, }; + uint8_t encoded_payload_[27] = { + 180, 0, 0, 0, 3, 0, 1, 0, 10, 0, 15, 1, 0, 10, + 0, 39, 232, 3, 244, 1, 100, 200, 150, 100, 150, 100, 0, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[27]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 27); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 27), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 27); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 27), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[27]; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode( + &buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 27), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[27]; + + for (uint8_t i = 0; i < 27; i++) { + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 27); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrGriddedCorrectionBounds, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 27); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; - sbp_msg_ssr_gridded_correction_bounds_t test_msg{}; - test_msg.grid_point_id = 1000; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 0; - test_msg.header.sol_id = 0; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 10; - test_msg.n_sats = 0; - test_msg.ssr_iod_atmo = 15; - test_msg.tile_id = 10; - test_msg.tile_set_id = 1; - test_msg.tropo_delay_correction.hydro = 500; - test_msg.tropo_delay_correction.stddev = 200; - test_msg.tropo_delay_correction.wet = 100; - test_msg.tropo_qi = 39; - test_msg.tropo_v_hydro_bound_mu = 150; - test_msg.tropo_v_hydro_bound_sig = 100; - test_msg.tropo_v_wet_bound_mu = 150; - test_msg.tropo_v_wet_bound_sig = 100; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.grid_point_id, 1000) - << "incorrect value for last_msg_.grid_point_id, expected 1000, is " - << last_msg_.grid_point_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 0) - << "incorrect value for last_msg_.header.seq_num, expected 0, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 0) - << "incorrect value for last_msg_.header.sol_id, expected 0, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 10) - << "incorrect value for last_msg_.header.update_interval, expected 10, " - "is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.n_sats, 0) - << "incorrect value for last_msg_.n_sats, expected 0, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.ssr_iod_atmo, 15) - << "incorrect value for last_msg_.ssr_iod_atmo, expected 15, is " - << last_msg_.ssr_iod_atmo; - EXPECT_EQ(last_msg_.tile_id, 10) - << "incorrect value for last_msg_.tile_id, expected 10, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 1) - << "incorrect value for last_msg_.tile_set_id, expected 1, is " - << last_msg_.tile_set_id; - EXPECT_EQ(last_msg_.tropo_delay_correction.hydro, 500) - << "incorrect value for last_msg_.tropo_delay_correction.hydro, expected " - "500, is " - << last_msg_.tropo_delay_correction.hydro; - EXPECT_EQ(last_msg_.tropo_delay_correction.stddev, 200) - << "incorrect value for last_msg_.tropo_delay_correction.stddev, " - "expected 200, is " - << last_msg_.tropo_delay_correction.stddev; - EXPECT_EQ(last_msg_.tropo_delay_correction.wet, 100) - << "incorrect value for last_msg_.tropo_delay_correction.wet, expected " - "100, is " - << last_msg_.tropo_delay_correction.wet; - EXPECT_EQ(last_msg_.tropo_qi, 39) - << "incorrect value for last_msg_.tropo_qi, expected 39, is " - << last_msg_.tropo_qi; - EXPECT_EQ(last_msg_.tropo_v_hydro_bound_mu, 150) - << "incorrect value for last_msg_.tropo_v_hydro_bound_mu, expected 150, " - "is " - << last_msg_.tropo_v_hydro_bound_mu; - EXPECT_EQ(last_msg_.tropo_v_hydro_bound_sig, 100) - << "incorrect value for last_msg_.tropo_v_hydro_bound_sig, expected 100, " - "is " - << last_msg_.tropo_v_hydro_bound_sig; - EXPECT_EQ(last_msg_.tropo_v_wet_bound_mu, 150) - << "incorrect value for last_msg_.tropo_v_wet_bound_mu, expected 150, is " - << last_msg_.tropo_v_wet_bound_mu; - EXPECT_EQ(last_msg_.tropo_v_wet_bound_sig, 100) - << "incorrect value for last_msg_.tropo_v_wet_bound_sig, expected 100, " - "is " - << last_msg_.tropo_v_wet_bound_sig; + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_gridded_correction_bounds_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrGriddedCorrectionBounds, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.grid_point_id, greater.grid_point_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod_atmo, greater.ssr_iod_atmo); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.hydro, + greater.tropo_delay_correction.hydro); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.stddev, + greater.tropo_delay_correction.stddev); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_delay_correction.wet, + greater.tropo_delay_correction.wet); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_qi, greater.tropo_qi); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_hydro_bound_mu, + greater.tropo_v_hydro_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_hydro_bound_sig, + greater.tropo_v_hydro_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_wet_bound_mu, + greater.tropo_v_wet_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_gridded_correction_bounds_t lesser = info.test_msg; + sbp_msg_ssr_gridded_correction_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.tropo_v_wet_bound_sig, + greater.tropo_v_wet_bound_sig); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrGriddedCorrectionBounds); + EXPECT_STREQ( + sbp::MessageTraits::name, + "MSG_SSR_GRIDDED_CORRECTION_BOUNDS"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_gridded_correction_bounds_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_gridded_correction_bounds_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_gridded_correction_bounds, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_gridded_correction_bounds, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[27]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 27); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 27), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_gridded_correction_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 27); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrGriddedCorrectionBounds, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrGriddedCorrectionBounds1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrGriddedCorrectionBounds, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBounds.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBounds.cc index adc02bcbcf..46a2b5b899 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBounds.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBounds.cc @@ -16,211 +16,806 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrOrbitClockBounds0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0 : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrOrbitClockBounds0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0() { + assign(test_msg_.const_id, 1); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.sol_id, 48); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 3); + assign(test_msg_.n_sats, 2); + + assign(test_msg_.orbit_clock_bounds[0].clock_bound_mu, 39); + assign(test_msg_.orbit_clock_bounds[0].clock_bound_sig, 1); + assign(test_msg_.orbit_clock_bounds[0].orb_along_bound_mu, 38); + assign(test_msg_.orbit_clock_bounds[0].orb_along_bound_sig, 2); + assign(test_msg_.orbit_clock_bounds[0].orb_cross_bound_mu, 37); + assign(test_msg_.orbit_clock_bounds[0].orb_cross_bound_sig, 3); + assign(test_msg_.orbit_clock_bounds[0].orb_radial_bound_mu, 39); + assign(test_msg_.orbit_clock_bounds[0].orb_radial_bound_sig, 1); + assign(test_msg_.orbit_clock_bounds[0].sat_id, 24); + + assign(test_msg_.orbit_clock_bounds[1].clock_bound_mu, 39); + assign(test_msg_.orbit_clock_bounds[1].clock_bound_sig, 1); + assign(test_msg_.orbit_clock_bounds[1].orb_along_bound_mu, 38); + assign(test_msg_.orbit_clock_bounds[1].orb_along_bound_sig, 2); + assign(test_msg_.orbit_clock_bounds[1].orb_cross_bound_mu, 37); + assign(test_msg_.orbit_clock_bounds[1].orb_cross_bound_sig, 3); + assign(test_msg_.orbit_clock_bounds[1].orb_radial_bound_mu, 39); + assign(test_msg_.orbit_clock_bounds[1].orb_radial_bound_sig, 1); + assign(test_msg_.orbit_clock_bounds[1].sat_id, 3); + assign(test_msg_.ssr_iod, 15); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_orbit_clock_bounds_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_orbit_clock_bounds_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrOrbitClockBounds, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_orbit_clock_bounds_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrOrbitClockBounds); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_orbit_clock_bounds, + sizeof(msg->ssr_orbit_clock_bounds)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_orbit_clock_bounds_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_orbit_clock_bounds, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrOrbitClockBounds); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x5515; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 31; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_orbit_clock_bounds_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_orbit_clock_bounds_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_orbit_clock_bounds_t &lesser, + const sbp_msg_ssr_orbit_clock_bounds_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_orbit_clock_bounds_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_orbit_clock_bounds_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrOrbitClockBounds, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrOrbitClockBounds, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrOrbitClockBounds, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrOrbitClockBounds, &wrapped_greater, + &wrapped_lesser), + 0); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrOrbitClockBounds0, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_orbit_clock_bounds_t test_msg_{}; + uint8_t encoded_frame_[31 + 8] = { 85, 222, 5, 66, 0, 31, 180, 0, 0, 0, 3, 0, 1, 2, 3, 48, 15, 1, 2, 24, 39, 38, 37, 1, 2, 3, 39, 1, 3, 39, 38, 37, 1, 2, 3, 39, 1, 21, 85, }; + uint8_t encoded_payload_[31] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 48, 15, 1, 2, 24, 39, 38, + 37, 1, 2, 3, 39, 1, 3, 39, 38, 37, 1, 2, 3, 39, 1, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrOrbitClockBounds, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrOrbitClockBounds, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + for (uint8_t i = 0; i < 31; i++) { + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrOrbitClockBounds, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_orbit_clock_bounds_t t{}; + return sbp_msg_ssr_orbit_clock_bounds_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_orbit_clock_bounds_t t{}; + t.n_sats = 1; + return sbp_msg_ssr_orbit_clock_bounds_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_ssr_orbit_clock_bounds_t test_msg{}; - test_msg.const_id = 1; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 2; - test_msg.header.sol_id = 48; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 3; - test_msg.n_sats = 2; - - test_msg.orbit_clock_bounds[0].clock_bound_mu = 39; - test_msg.orbit_clock_bounds[0].clock_bound_sig = 1; - test_msg.orbit_clock_bounds[0].orb_along_bound_mu = 38; - test_msg.orbit_clock_bounds[0].orb_along_bound_sig = 2; - test_msg.orbit_clock_bounds[0].orb_cross_bound_mu = 37; - test_msg.orbit_clock_bounds[0].orb_cross_bound_sig = 3; - test_msg.orbit_clock_bounds[0].orb_radial_bound_mu = 39; - test_msg.orbit_clock_bounds[0].orb_radial_bound_sig = 1; - test_msg.orbit_clock_bounds[0].sat_id = 24; - - test_msg.orbit_clock_bounds[1].clock_bound_mu = 39; - test_msg.orbit_clock_bounds[1].clock_bound_sig = 1; - test_msg.orbit_clock_bounds[1].orb_along_bound_mu = 38; - test_msg.orbit_clock_bounds[1].orb_along_bound_sig = 2; - test_msg.orbit_clock_bounds[1].orb_cross_bound_mu = 37; - test_msg.orbit_clock_bounds[1].orb_cross_bound_sig = 3; - test_msg.orbit_clock_bounds[1].orb_radial_bound_mu = 39; - test_msg.orbit_clock_bounds[1].orb_radial_bound_sig = 1; - test_msg.orbit_clock_bounds[1].sat_id = 3; - test_msg.ssr_iod = 15; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.const_id, 1) - << "incorrect value for last_msg_.const_id, expected 1, is " - << last_msg_.const_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 48) - << "incorrect value for last_msg_.header.sol_id, expected 48, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 3) - << "incorrect value for last_msg_.header.update_interval, expected 3, is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.n_sats, 2) - << "incorrect value for last_msg_.n_sats, expected 2, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].clock_bound_mu, 39) - << "incorrect value for last_msg_.orbit_clock_bounds[0].clock_bound_mu, " - "expected 39, is " - << last_msg_.orbit_clock_bounds[0].clock_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].clock_bound_sig, 1) - << "incorrect value for last_msg_.orbit_clock_bounds[0].clock_bound_sig, " - "expected 1, is " - << last_msg_.orbit_clock_bounds[0].clock_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_along_bound_mu, 38) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_along_bound_mu, expected 38, is " - << last_msg_.orbit_clock_bounds[0].orb_along_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_along_bound_sig, 2) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_along_bound_sig, expected 2, is " - << last_msg_.orbit_clock_bounds[0].orb_along_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_cross_bound_mu, 37) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_cross_bound_mu, expected 37, is " - << last_msg_.orbit_clock_bounds[0].orb_cross_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_cross_bound_sig, 3) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_cross_bound_sig, expected 3, is " - << last_msg_.orbit_clock_bounds[0].orb_cross_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_radial_bound_mu, 39) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_radial_bound_mu, expected 39, is " - << last_msg_.orbit_clock_bounds[0].orb_radial_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].orb_radial_bound_sig, 1) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[0].orb_radial_bound_sig, expected 1, is " - << last_msg_.orbit_clock_bounds[0].orb_radial_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[0].sat_id, 24) - << "incorrect value for last_msg_.orbit_clock_bounds[0].sat_id, expected " - "24, is " - << last_msg_.orbit_clock_bounds[0].sat_id; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].clock_bound_mu, 39) - << "incorrect value for last_msg_.orbit_clock_bounds[1].clock_bound_mu, " - "expected 39, is " - << last_msg_.orbit_clock_bounds[1].clock_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].clock_bound_sig, 1) - << "incorrect value for last_msg_.orbit_clock_bounds[1].clock_bound_sig, " - "expected 1, is " - << last_msg_.orbit_clock_bounds[1].clock_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_along_bound_mu, 38) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_along_bound_mu, expected 38, is " - << last_msg_.orbit_clock_bounds[1].orb_along_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_along_bound_sig, 2) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_along_bound_sig, expected 2, is " - << last_msg_.orbit_clock_bounds[1].orb_along_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_cross_bound_mu, 37) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_cross_bound_mu, expected 37, is " - << last_msg_.orbit_clock_bounds[1].orb_cross_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_cross_bound_sig, 3) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_cross_bound_sig, expected 3, is " - << last_msg_.orbit_clock_bounds[1].orb_cross_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_radial_bound_mu, 39) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_radial_bound_mu, expected 39, is " - << last_msg_.orbit_clock_bounds[1].orb_radial_bound_mu; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].orb_radial_bound_sig, 1) - << "incorrect value for " - "last_msg_.orbit_clock_bounds[1].orb_radial_bound_sig, expected 1, is " - << last_msg_.orbit_clock_bounds[1].orb_radial_bound_sig; - EXPECT_EQ(last_msg_.orbit_clock_bounds[1].sat_id, 3) - << "incorrect value for last_msg_.orbit_clock_bounds[1].sat_id, expected " - "3, is " - << last_msg_.orbit_clock_bounds[1].sat_id; - EXPECT_EQ(last_msg_.ssr_iod, 15) - << "incorrect value for last_msg_.ssr_iod, expected 15, is " - << last_msg_.ssr_iod; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrOrbitClockBounds, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.const_id, greater.const_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].clock_bound_mu, + greater.orbit_clock_bounds[0].clock_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].clock_bound_sig, + greater.orbit_clock_bounds[0].clock_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_along_bound_mu, + greater.orbit_clock_bounds[0].orb_along_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_along_bound_sig, + greater.orbit_clock_bounds[0].orb_along_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_cross_bound_mu, + greater.orbit_clock_bounds[0].orb_cross_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_cross_bound_sig, + greater.orbit_clock_bounds[0].orb_cross_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_radial_bound_mu, + greater.orbit_clock_bounds[0].orb_radial_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].orb_radial_bound_sig, + greater.orbit_clock_bounds[0].orb_radial_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[0].sat_id, + greater.orbit_clock_bounds[0].sat_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].clock_bound_mu, + greater.orbit_clock_bounds[1].clock_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].clock_bound_sig, + greater.orbit_clock_bounds[1].clock_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_along_bound_mu, + greater.orbit_clock_bounds[1].orb_along_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_along_bound_sig, + greater.orbit_clock_bounds[1].orb_along_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_cross_bound_mu, + greater.orbit_clock_bounds[1].orb_cross_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_cross_bound_sig, + greater.orbit_clock_bounds[1].orb_cross_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_radial_bound_mu, + greater.orbit_clock_bounds[1].orb_radial_bound_mu); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].orb_radial_bound_sig, + greater.orbit_clock_bounds[1].orb_radial_bound_sig); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.orbit_clock_bounds[1].sat_id, + greater.orbit_clock_bounds[1].sat_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod, greater.ssr_iod); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrOrbitClockBounds); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_ORBIT_CLOCK_BOUNDS"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_orbit_clock_bounds_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_orbit_clock_bounds_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_orbit_clock_bounds, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_orbit_clock_bounds, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrOrbitClockBounds, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBounds0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrOrbitClockBounds, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation.cc index eaeb52f6e8..fdf3b3c5a2 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation.cc @@ -16,174 +16,746 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0 + : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0() { + assign(test_msg_.const_id, 1); + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 2); + assign(test_msg_.header.sol_id, 48); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 3); + assign(test_msg_.orbit_clock_bounds_degradation.clock_bound_mu_dot, 194); + assign(test_msg_.orbit_clock_bounds_degradation.clock_bound_sig_dot, 193); + assign(test_msg_.orbit_clock_bounds_degradation.orb_along_bound_mu_dot, + 199); + assign(test_msg_.orbit_clock_bounds_degradation.orb_along_bound_sig_dot, + 196); + assign(test_msg_.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot, + 198); + assign(test_msg_.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot, + 195); + assign(test_msg_.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot, + 200); + assign(test_msg_.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot, + 197); + assign(test_msg_.sat_bitmask, 10); + assign(test_msg_.ssr_iod, 15); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler< + sbp_msg_ssr_orbit_clock_bounds_degradation_t> { + using sbp::MessageHandler< + sbp_msg_ssr_orbit_clock_bounds_degradation_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_orbit_clock_bounds_degradation_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrOrbitClockBoundsDegradation, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrOrbitClockBoundsDegradation); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_orbit_clock_bounds_degradation, + sizeof(msg->ssr_orbit_clock_bounds_degradation)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_orbit_clock_bounds_degradation_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_orbit_clock_bounds_degradation, + &test_msg_, sizeof(test_msg_)); + info.msg_type = + static_cast(SbpMsgSsrOrbitClockBoundsDegradation); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x75C8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 28; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_ssr_orbit_clock_bounds_degradation_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_orbit_clock_bounds_degradation_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests( + const sbp_msg_ssr_orbit_clock_bounds_degradation_t &lesser, + const sbp_msg_ssr_orbit_clock_bounds_degradation_t &greater) { + sbp_msg_t wrapped_lesser = sbp::MessageTraits< + sbp_msg_ssr_orbit_clock_bounds_degradation_t>::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = sbp::MessageTraits< + sbp_msg_ssr_orbit_clock_bounds_degradation_t>::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_cmp(&lesser, &lesser), + 0); + EXPECT_EQ( + sbp_msg_ssr_orbit_clock_bounds_degradation_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_orbit_clock_bounds_degradation_cmp(&lesser, &greater), + 0); + EXPECT_GT(sbp_msg_ssr_orbit_clock_bounds_degradation_cmp(&greater, &lesser), + 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrOrbitClockBoundsDegradation, + &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrOrbitClockBoundsDegradation, + &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrOrbitClockBoundsDegradation, + &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrOrbitClockBoundsDegradation, + &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_orbit_clock_bounds_degradation_t test_msg_{}; + uint8_t encoded_frame_[28 + 8] = { 85, 223, 5, 66, 0, 28, 180, 0, 0, 0, 3, 0, 1, 2, 3, 48, 15, 1, 10, 0, 0, 0, 0, 0, 0, 0, 200, 199, 198, 197, 196, 195, 194, 193, 200, 117, }; + uint8_t encoded_payload_[28] = { + 180, 0, 0, 0, 3, 0, 1, 2, 3, 48, 15, 1, 10, 0, + 0, 0, 0, 0, 0, 0, 200, 199, 198, 197, 196, 195, 194, 193, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp_msg_ssr_orbit_clock_bounds_degradation_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrOrbitClockBoundsDegradation, + &info.test_msg_wrapped), + info.payload_len); +} - sbp_msg_ssr_orbit_clock_bounds_degradation_t test_msg{}; - test_msg.const_id = 1; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 2; - test_msg.header.sol_id = 48; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 3; - test_msg.orbit_clock_bounds_degradation.clock_bound_mu_dot = 194; - test_msg.orbit_clock_bounds_degradation.clock_bound_sig_dot = 193; - test_msg.orbit_clock_bounds_degradation.orb_along_bound_mu_dot = 199; - test_msg.orbit_clock_bounds_degradation.orb_along_bound_sig_dot = 196; - test_msg.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot = 198; - test_msg.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot = 195; - test_msg.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot = 200; - test_msg.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot = 197; - test_msg.sat_bitmask = 10; - test_msg.ssr_iod = 15; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.const_id, 1) - << "incorrect value for last_msg_.const_id, expected 1, is " - << last_msg_.const_id; - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 2) - << "incorrect value for last_msg_.header.seq_num, expected 2, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 48) - << "incorrect value for last_msg_.header.sol_id, expected 48, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 3) - << "incorrect value for last_msg_.header.update_interval, expected 3, is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.clock_bound_mu_dot, 194) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.clock_bound_mu_dot, " - "expected 194, is " - << last_msg_.orbit_clock_bounds_degradation.clock_bound_mu_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.clock_bound_sig_dot, 193) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.clock_bound_sig_dot, " - "expected 193, is " - << last_msg_.orbit_clock_bounds_degradation.clock_bound_sig_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_along_bound_mu_dot, - 199) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_along_bound_mu_dot, " - "expected 199, is " - << last_msg_.orbit_clock_bounds_degradation.orb_along_bound_mu_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_along_bound_sig_dot, - 196) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_along_bound_sig_dot, " - "expected 196, is " - << last_msg_.orbit_clock_bounds_degradation.orb_along_bound_sig_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot, - 198) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot, " - "expected 198, is " - << last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot, - 195) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot, " - "expected 195, is " - << last_msg_.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot, - 200) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot, " - "expected 200, is " - << last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot; - EXPECT_EQ(last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot, - 197) - << "incorrect value for " - "last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot, " - "expected 197, is " - << last_msg_.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot; - EXPECT_EQ(last_msg_.sat_bitmask, 10) - << "incorrect value for last_msg_.sat_bitmask, expected 10, is " - << last_msg_.sat_bitmask; - EXPECT_EQ(last_msg_.ssr_iod, 15) - << "incorrect value for last_msg_.ssr_iod, expected 15, is " - << last_msg_.ssr_iod; +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[28]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 28); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 28), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrOrbitClockBoundsDegradation, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 28); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 28), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[28]; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_encode( + &buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 28), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[28]; + + for (uint8_t i = 0; i < 28; i++) { + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_encode( + &buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 28); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrOrbitClockBoundsDegradation, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 28); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_orbit_clock_bounds_degradation_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrOrbitClockBoundsDegradation, + info.sender_id, &info.test_msg_wrapped, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.const_id, greater.const_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.clock_bound_mu_dot, + greater.orbit_clock_bounds_degradation.clock_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.clock_bound_sig_dot, + greater.orbit_clock_bounds_degradation.clock_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_along_bound_mu_dot, + greater.orbit_clock_bounds_degradation.orb_along_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_along_bound_sig_dot, + greater.orbit_clock_bounds_degradation.orb_along_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot, + greater.orbit_clock_bounds_degradation.orb_cross_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot, + greater.orbit_clock_bounds_degradation.orb_cross_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot, + greater.orbit_clock_bounds_degradation.orb_radial_bound_mu_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater( + lesser.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot, + greater.orbit_clock_bounds_degradation.orb_radial_bound_sig_dot); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.sat_bitmask, greater.sat_bitmask); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_orbit_clock_bounds_degradation_t lesser = info.test_msg; + sbp_msg_ssr_orbit_clock_bounds_degradation_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod, greater.ssr_iod); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrOrbitClockBoundsDegradation); + EXPECT_STREQ( + sbp::MessageTraits::name, + "MSG_SSR_ORBIT_CLOCK_BOUNDS_DEGRADATION"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_orbit_clock_bounds_degradation_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_orbit_clock_bounds_degradation_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits< + sbp_msg_ssr_orbit_clock_bounds_degradation_t>::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ssr_orbit_clock_bounds_degradation, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_orbit_clock_bounds_degradation, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits:: + encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[28]; + uint8_t n_written; + + EXPECT_EQ( + sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 28); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 28), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_orbit_clock_bounds_degradation_t msg{}; + uint8_t n_read; + + EXPECT_EQ( + sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 28); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrOrbitClockBoundsDegradation, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrOrbitClockBoundsDegradation0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgSsrOrbitClockBoundsDegradation, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrSatelliteApc.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrSatelliteApc.cc index 6090676ff5..93871a6f05 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrSatelliteApc.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrSatelliteApc.cc @@ -16,244 +16,871 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrSatelliteApc0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrSatelliteApc0 : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrSatelliteApc0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrSatelliteApc0() { + assign(test_msg_.apc[0].pco[0], 1); + + assign(test_msg_.apc[0].pco[1], -1); + + assign(test_msg_.apc[0].pco[2], 729); + + assign(test_msg_.apc[0].pcv[0], 11); + + assign(test_msg_.apc[0].pcv[1], 10); + + assign(test_msg_.apc[0].pcv[2], 8); + + assign(test_msg_.apc[0].pcv[3], 5); + + assign(test_msg_.apc[0].pcv[4], 1); + + assign(test_msg_.apc[0].pcv[5], -4); + + assign(test_msg_.apc[0].pcv[6], -8); + + assign(test_msg_.apc[0].pcv[7], -10); + + assign(test_msg_.apc[0].pcv[8], -10); + + assign(test_msg_.apc[0].pcv[9], -10); + + assign(test_msg_.apc[0].pcv[10], -7); + + assign(test_msg_.apc[0].pcv[11], -4); + + assign(test_msg_.apc[0].pcv[12], 0); + + assign(test_msg_.apc[0].pcv[13], 6); + + assign(test_msg_.apc[0].pcv[14], 12); + + assign(test_msg_.apc[0].pcv[15], 22); + + assign(test_msg_.apc[0].pcv[16], 30); + + assign(test_msg_.apc[0].pcv[17], 41); + + assign(test_msg_.apc[0].pcv[18], 41); + + assign(test_msg_.apc[0].pcv[19], 41); + + assign(test_msg_.apc[0].pcv[20], 41); + assign(test_msg_.apc[0].sat_info, 4); + assign(test_msg_.apc[0].sid.code, 0); + assign(test_msg_.apc[0].sid.sat, 2); + assign(test_msg_.apc[0].svn, 61); + assign(test_msg_.iod_ssr, 3); + assign(test_msg_.n_apc, 1); + assign(test_msg_.sol_id, 2); + assign(test_msg_.time.tow, 604799); + assign(test_msg_.time.wn, 2222); + assign(test_msg_.update_interval, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_satellite_apc_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_satellite_apc_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrSatelliteApc, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_satellite_apc_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrSatelliteApc); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_satellite_apc, + sizeof(msg->ssr_satellite_apc)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_satellite_apc_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_satellite_apc, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrSatelliteApc); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0xA190; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 41; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_satellite_apc_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_satellite_apc_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_satellite_apc_t &lesser, + const sbp_msg_ssr_satellite_apc_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_satellite_apc_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_satellite_apc_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_satellite_apc_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_satellite_apc_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrSatelliteApc, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrSatelliteApc, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrSatelliteApc, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrSatelliteApc, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_ssr_MsgSsrSatelliteApc0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_satellite_apc_t test_msg_{}; + uint8_t encoded_frame_[41 + 8] = { 85, 5, 6, 0, 0, 41, 127, 58, 9, 0, 174, 8, 1, 2, 3, 2, 0, 4, 61, 0, 1, 0, 255, 255, 217, 2, 11, 10, 8, 5, 1, 252, 248, 246, 246, 246, 249, 252, 0, 6, 12, 22, 30, 41, 41, 41, 41, 144, 161, }; + uint8_t encoded_payload_[41] = { + 127, 58, 9, 0, 174, 8, 1, 2, 3, 2, 0, 4, 61, 0, + 1, 0, 255, 255, 217, 2, 11, 10, 8, 5, 1, 252, 248, 246, + 246, 246, 249, 252, 0, 6, 12, 22, 30, 41, 41, 41, 41, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_satellite_apc_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSsrSatelliteApc, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_satellite_apc_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrSatelliteApc, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + + EXPECT_EQ(sbp_msg_ssr_satellite_apc_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + + for (uint8_t i = 0; i < 41; i++) { + EXPECT_EQ( + sbp_msg_ssr_satellite_apc_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_satellite_apc_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_satellite_apc_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSsrSatelliteApc, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_satellite_apc_t msg{}; - sbp_msg_ssr_satellite_apc_t test_msg{}; + EXPECT_EQ(sbp_msg_ssr_satellite_apc_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_satellite_apc_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_satellite_apc_t t{}; + return sbp_msg_ssr_satellite_apc_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_satellite_apc_t t{}; + t.n_apc = 1; + return sbp_msg_ssr_satellite_apc_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_satellite_apc_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} - test_msg.apc[0].pco[0] = 1; +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.apc[0].pco[1] = -1; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - test_msg.apc[0].pco[2] = 729; + CHandler handler{&state}; - test_msg.apc[0].pcv[0] = 11; + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } - test_msg.apc[0].pcv[1] = 10; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.apc[0].pcv[2] = 8; +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.apc[0].pcv[3] = 5; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.apc[0].pcv[4] = 1; + EXPECT_EQ(sbp_msg_ssr_satellite_apc_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.apc[0].pcv[5] = -4; +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.apc[0].pcv[6] = -8; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.apc[0].pcv[7] = -10; - - test_msg.apc[0].pcv[8] = -10; - - test_msg.apc[0].pcv[9] = -10; - - test_msg.apc[0].pcv[10] = -7; - - test_msg.apc[0].pcv[11] = -4; - - test_msg.apc[0].pcv[12] = 0; - - test_msg.apc[0].pcv[13] = 6; - - test_msg.apc[0].pcv[14] = 12; - - test_msg.apc[0].pcv[15] = 22; - - test_msg.apc[0].pcv[16] = 30; - - test_msg.apc[0].pcv[17] = 41; - - test_msg.apc[0].pcv[18] = 41; - - test_msg.apc[0].pcv[19] = 41; - - test_msg.apc[0].pcv[20] = 41; - test_msg.apc[0].sat_info = 4; - test_msg.apc[0].sid.code = 0; - test_msg.apc[0].sid.sat = 2; - test_msg.apc[0].svn = 61; - test_msg.iod_ssr = 3; - test_msg.n_apc = 1; - test_msg.sol_id = 2; - test_msg.time.tow = 604799; - test_msg.time.wn = 2222; - test_msg.update_interval = 1; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.apc[0].pco[0], 1) - << "incorrect value for last_msg_.apc[0].pco[0], expected 1, is " - << last_msg_.apc[0].pco[0]; - EXPECT_EQ(last_msg_.apc[0].pco[1], -1) - << "incorrect value for last_msg_.apc[0].pco[1], expected -1, is " - << last_msg_.apc[0].pco[1]; - EXPECT_EQ(last_msg_.apc[0].pco[2], 729) - << "incorrect value for last_msg_.apc[0].pco[2], expected 729, is " - << last_msg_.apc[0].pco[2]; - EXPECT_EQ(last_msg_.apc[0].pcv[0], 11) - << "incorrect value for last_msg_.apc[0].pcv[0], expected 11, is " - << last_msg_.apc[0].pcv[0]; - EXPECT_EQ(last_msg_.apc[0].pcv[1], 10) - << "incorrect value for last_msg_.apc[0].pcv[1], expected 10, is " - << last_msg_.apc[0].pcv[1]; - EXPECT_EQ(last_msg_.apc[0].pcv[2], 8) - << "incorrect value for last_msg_.apc[0].pcv[2], expected 8, is " - << last_msg_.apc[0].pcv[2]; - EXPECT_EQ(last_msg_.apc[0].pcv[3], 5) - << "incorrect value for last_msg_.apc[0].pcv[3], expected 5, is " - << last_msg_.apc[0].pcv[3]; - EXPECT_EQ(last_msg_.apc[0].pcv[4], 1) - << "incorrect value for last_msg_.apc[0].pcv[4], expected 1, is " - << last_msg_.apc[0].pcv[4]; - EXPECT_EQ(last_msg_.apc[0].pcv[5], -4) - << "incorrect value for last_msg_.apc[0].pcv[5], expected -4, is " - << last_msg_.apc[0].pcv[5]; - EXPECT_EQ(last_msg_.apc[0].pcv[6], -8) - << "incorrect value for last_msg_.apc[0].pcv[6], expected -8, is " - << last_msg_.apc[0].pcv[6]; - EXPECT_EQ(last_msg_.apc[0].pcv[7], -10) - << "incorrect value for last_msg_.apc[0].pcv[7], expected -10, is " - << last_msg_.apc[0].pcv[7]; - EXPECT_EQ(last_msg_.apc[0].pcv[8], -10) - << "incorrect value for last_msg_.apc[0].pcv[8], expected -10, is " - << last_msg_.apc[0].pcv[8]; - EXPECT_EQ(last_msg_.apc[0].pcv[9], -10) - << "incorrect value for last_msg_.apc[0].pcv[9], expected -10, is " - << last_msg_.apc[0].pcv[9]; - EXPECT_EQ(last_msg_.apc[0].pcv[10], -7) - << "incorrect value for last_msg_.apc[0].pcv[10], expected -7, is " - << last_msg_.apc[0].pcv[10]; - EXPECT_EQ(last_msg_.apc[0].pcv[11], -4) - << "incorrect value for last_msg_.apc[0].pcv[11], expected -4, is " - << last_msg_.apc[0].pcv[11]; - EXPECT_EQ(last_msg_.apc[0].pcv[12], 0) - << "incorrect value for last_msg_.apc[0].pcv[12], expected 0, is " - << last_msg_.apc[0].pcv[12]; - EXPECT_EQ(last_msg_.apc[0].pcv[13], 6) - << "incorrect value for last_msg_.apc[0].pcv[13], expected 6, is " - << last_msg_.apc[0].pcv[13]; - EXPECT_EQ(last_msg_.apc[0].pcv[14], 12) - << "incorrect value for last_msg_.apc[0].pcv[14], expected 12, is " - << last_msg_.apc[0].pcv[14]; - EXPECT_EQ(last_msg_.apc[0].pcv[15], 22) - << "incorrect value for last_msg_.apc[0].pcv[15], expected 22, is " - << last_msg_.apc[0].pcv[15]; - EXPECT_EQ(last_msg_.apc[0].pcv[16], 30) - << "incorrect value for last_msg_.apc[0].pcv[16], expected 30, is " - << last_msg_.apc[0].pcv[16]; - EXPECT_EQ(last_msg_.apc[0].pcv[17], 41) - << "incorrect value for last_msg_.apc[0].pcv[17], expected 41, is " - << last_msg_.apc[0].pcv[17]; - EXPECT_EQ(last_msg_.apc[0].pcv[18], 41) - << "incorrect value for last_msg_.apc[0].pcv[18], expected 41, is " - << last_msg_.apc[0].pcv[18]; - EXPECT_EQ(last_msg_.apc[0].pcv[19], 41) - << "incorrect value for last_msg_.apc[0].pcv[19], expected 41, is " - << last_msg_.apc[0].pcv[19]; - EXPECT_EQ(last_msg_.apc[0].pcv[20], 41) - << "incorrect value for last_msg_.apc[0].pcv[20], expected 41, is " - << last_msg_.apc[0].pcv[20]; - EXPECT_EQ(last_msg_.apc[0].sat_info, 4) - << "incorrect value for last_msg_.apc[0].sat_info, expected 4, is " - << last_msg_.apc[0].sat_info; - EXPECT_EQ(last_msg_.apc[0].sid.code, 0) - << "incorrect value for last_msg_.apc[0].sid.code, expected 0, is " - << last_msg_.apc[0].sid.code; - EXPECT_EQ(last_msg_.apc[0].sid.sat, 2) - << "incorrect value for last_msg_.apc[0].sid.sat, expected 2, is " - << last_msg_.apc[0].sid.sat; - EXPECT_EQ(last_msg_.apc[0].svn, 61) - << "incorrect value for last_msg_.apc[0].svn, expected 61, is " - << last_msg_.apc[0].svn; - EXPECT_EQ(last_msg_.iod_ssr, 3) - << "incorrect value for last_msg_.iod_ssr, expected 3, is " - << last_msg_.iod_ssr; - EXPECT_EQ(last_msg_.n_apc, 1) - << "incorrect value for last_msg_.n_apc, expected 1, is " - << last_msg_.n_apc; - EXPECT_EQ(last_msg_.sol_id, 2) - << "incorrect value for last_msg_.sol_id, expected 2, is " - << last_msg_.sol_id; - EXPECT_EQ(last_msg_.time.tow, 604799) - << "incorrect value for last_msg_.time.tow, expected 604799, is " - << last_msg_.time.tow; - EXPECT_EQ(last_msg_.time.wn, 2222) - << "incorrect value for last_msg_.time.wn, expected 2222, is " - << last_msg_.time.wn; - EXPECT_EQ(last_msg_.update_interval, 1) - << "incorrect value for last_msg_.update_interval, expected 1, is " - << last_msg_.update_interval; + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrSatelliteApc, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pco[0], greater.apc[0].pco[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pco[1], greater.apc[0].pco[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pco[2], greater.apc[0].pco[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[0], greater.apc[0].pcv[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[1], greater.apc[0].pcv[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[2], greater.apc[0].pcv[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[3], greater.apc[0].pcv[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[4], greater.apc[0].pcv[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[5], greater.apc[0].pcv[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[6], greater.apc[0].pcv[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[7], greater.apc[0].pcv[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[8], greater.apc[0].pcv[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[9], greater.apc[0].pcv[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[10], greater.apc[0].pcv[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[11], greater.apc[0].pcv[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[12], greater.apc[0].pcv[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[13], greater.apc[0].pcv[13]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[14], greater.apc[0].pcv[14]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[15], greater.apc[0].pcv[15]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[16], greater.apc[0].pcv[16]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[17], greater.apc[0].pcv[17]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[18], greater.apc[0].pcv[18]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[19], greater.apc[0].pcv[19]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].pcv[20], greater.apc[0].pcv[20]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].sat_info, greater.apc[0].sat_info); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].sid.code, greater.apc[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].sid.sat, greater.apc[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.apc[0].svn, greater.apc[0].svn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.iod_ssr, greater.iod_ssr); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.n_apc, greater.n_apc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.sol_id, greater.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.time.tow, greater.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.time.wn, greater.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_satellite_apc_t lesser = info.test_msg; + sbp_msg_ssr_satellite_apc_t greater = info.test_msg; + make_lesser_greater(lesser.update_interval, greater.update_interval); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrSatelliteApc); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_SATELLITE_APC"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_satellite_apc_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ssr_satellite_apc_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_satellite_apc, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ssr_satellite_apc, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[41]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 41); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 41), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_satellite_apc_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 41); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrSatelliteApc, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrSatelliteApc0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrSatelliteApc, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrStecCorrection.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrStecCorrection.cc index 70a61b2b86..ef3b5d41b7 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrStecCorrection.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrStecCorrection.cc @@ -16,202 +16,788 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrStecCorrection0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrStecCorrection0 : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrStecCorrection0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrStecCorrection0() { + assign(test_msg_.header.num_msgs, 1); + assign(test_msg_.header.seq_num, 1); + assign(test_msg_.header.sol_id, 0); + assign(test_msg_.header.time.tow, 180); + assign(test_msg_.header.time.wn, 3); + assign(test_msg_.header.update_interval, 10); + assign(test_msg_.n_sats, 2); + assign(test_msg_.ssr_iod_atmo, 15); + + assign(test_msg_.stec_sat_list[0].stec_coeff[0], 63); + + assign(test_msg_.stec_sat_list[0].stec_coeff[1], 62); + + assign(test_msg_.stec_sat_list[0].stec_coeff[2], 61); + + assign(test_msg_.stec_sat_list[0].stec_coeff[3], 60); + assign(test_msg_.stec_sat_list[0].stec_quality_indicator, 1); + assign(test_msg_.stec_sat_list[0].sv_id.constellation, 1); + assign(test_msg_.stec_sat_list[0].sv_id.satId, 1); + + assign(test_msg_.stec_sat_list[1].stec_coeff[0], 63); + + assign(test_msg_.stec_sat_list[1].stec_coeff[1], 64); + + assign(test_msg_.stec_sat_list[1].stec_coeff[2], 65); + + assign(test_msg_.stec_sat_list[1].stec_coeff[3], 66); + assign(test_msg_.stec_sat_list[1].stec_quality_indicator, 5); + assign(test_msg_.stec_sat_list[1].sv_id.constellation, 15); + assign(test_msg_.stec_sat_list[1].sv_id.satId, 31); + assign(test_msg_.tile_id, 10); + assign(test_msg_.tile_set_id, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_stec_correction_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_stec_correction_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrStecCorrection, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_stec_correction_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrStecCorrection); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_stec_correction, + sizeof(msg->ssr_stec_correction)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_stec_correction_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_stec_correction, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrStecCorrection); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x3277; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 38; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_stec_correction_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_stec_correction_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_stec_correction_t &lesser, + const sbp_msg_ssr_stec_correction_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_stec_correction_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_stec_correction_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_stec_correction_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_stec_correction_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrStecCorrection, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrStecCorrection, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrStecCorrection, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrStecCorrection, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrStecCorrection0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_stec_correction_t test_msg_{}; + uint8_t encoded_frame_[38 + 8] = { 85, 253, 5, 66, 0, 38, 180, 0, 0, 0, 3, 0, 1, 1, 10, 0, 15, 1, 0, 10, 0, 2, 1, 1, 1, 63, 0, 62, 0, 61, 0, 60, 0, 31, 15, 5, 63, 0, 64, 0, 65, 0, 66, 0, 119, 50, }; + uint8_t encoded_payload_[38] = { + 180, 0, 0, 0, 3, 0, 1, 1, 10, 0, 15, 1, 0, 10, 0, 2, 1, 1, 1, + 63, 0, 62, 0, 61, 0, 60, 0, 31, 15, 5, 63, 0, 64, 0, 65, 0, 66, 0, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_stec_correction_encoded_len(&info.test_msg), + info.payload_len); - sbp_msg_ssr_stec_correction_t test_msg{}; - test_msg.header.num_msgs = 1; - test_msg.header.seq_num = 1; - test_msg.header.sol_id = 0; - test_msg.header.time.tow = 180; - test_msg.header.time.wn = 3; - test_msg.header.update_interval = 10; - test_msg.n_sats = 2; - test_msg.ssr_iod_atmo = 15; - - test_msg.stec_sat_list[0].stec_coeff[0] = 63; - - test_msg.stec_sat_list[0].stec_coeff[1] = 62; - - test_msg.stec_sat_list[0].stec_coeff[2] = 61; - - test_msg.stec_sat_list[0].stec_coeff[3] = 60; - test_msg.stec_sat_list[0].stec_quality_indicator = 1; - test_msg.stec_sat_list[0].sv_id.constellation = 1; - test_msg.stec_sat_list[0].sv_id.satId = 1; - - test_msg.stec_sat_list[1].stec_coeff[0] = 63; - - test_msg.stec_sat_list[1].stec_coeff[1] = 64; - - test_msg.stec_sat_list[1].stec_coeff[2] = 65; - - test_msg.stec_sat_list[1].stec_coeff[3] = 66; - test_msg.stec_sat_list[1].stec_quality_indicator = 5; - test_msg.stec_sat_list[1].sv_id.constellation = 15; - test_msg.stec_sat_list[1].sv_id.satId = 31; - test_msg.tile_id = 10; - test_msg.tile_set_id = 1; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.header.num_msgs, 1) - << "incorrect value for last_msg_.header.num_msgs, expected 1, is " - << last_msg_.header.num_msgs; - EXPECT_EQ(last_msg_.header.seq_num, 1) - << "incorrect value for last_msg_.header.seq_num, expected 1, is " - << last_msg_.header.seq_num; - EXPECT_EQ(last_msg_.header.sol_id, 0) - << "incorrect value for last_msg_.header.sol_id, expected 0, is " - << last_msg_.header.sol_id; - EXPECT_EQ(last_msg_.header.time.tow, 180) - << "incorrect value for last_msg_.header.time.tow, expected 180, is " - << last_msg_.header.time.tow; - EXPECT_EQ(last_msg_.header.time.wn, 3) - << "incorrect value for last_msg_.header.time.wn, expected 3, is " - << last_msg_.header.time.wn; - EXPECT_EQ(last_msg_.header.update_interval, 10) - << "incorrect value for last_msg_.header.update_interval, expected 10, " - "is " - << last_msg_.header.update_interval; - EXPECT_EQ(last_msg_.n_sats, 2) - << "incorrect value for last_msg_.n_sats, expected 2, is " - << last_msg_.n_sats; - EXPECT_EQ(last_msg_.ssr_iod_atmo, 15) - << "incorrect value for last_msg_.ssr_iod_atmo, expected 15, is " - << last_msg_.ssr_iod_atmo; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_coeff[0], 63) - << "incorrect value for last_msg_.stec_sat_list[0].stec_coeff[0], " - "expected 63, is " - << last_msg_.stec_sat_list[0].stec_coeff[0]; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_coeff[1], 62) - << "incorrect value for last_msg_.stec_sat_list[0].stec_coeff[1], " - "expected 62, is " - << last_msg_.stec_sat_list[0].stec_coeff[1]; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_coeff[2], 61) - << "incorrect value for last_msg_.stec_sat_list[0].stec_coeff[2], " - "expected 61, is " - << last_msg_.stec_sat_list[0].stec_coeff[2]; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_coeff[3], 60) - << "incorrect value for last_msg_.stec_sat_list[0].stec_coeff[3], " - "expected 60, is " - << last_msg_.stec_sat_list[0].stec_coeff[3]; - EXPECT_EQ(last_msg_.stec_sat_list[0].stec_quality_indicator, 1) - << "incorrect value for " - "last_msg_.stec_sat_list[0].stec_quality_indicator, expected 1, is " - << last_msg_.stec_sat_list[0].stec_quality_indicator; - EXPECT_EQ(last_msg_.stec_sat_list[0].sv_id.constellation, 1) - << "incorrect value for last_msg_.stec_sat_list[0].sv_id.constellation, " - "expected 1, is " - << last_msg_.stec_sat_list[0].sv_id.constellation; - EXPECT_EQ(last_msg_.stec_sat_list[0].sv_id.satId, 1) - << "incorrect value for last_msg_.stec_sat_list[0].sv_id.satId, expected " - "1, is " - << last_msg_.stec_sat_list[0].sv_id.satId; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_coeff[0], 63) - << "incorrect value for last_msg_.stec_sat_list[1].stec_coeff[0], " - "expected 63, is " - << last_msg_.stec_sat_list[1].stec_coeff[0]; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_coeff[1], 64) - << "incorrect value for last_msg_.stec_sat_list[1].stec_coeff[1], " - "expected 64, is " - << last_msg_.stec_sat_list[1].stec_coeff[1]; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_coeff[2], 65) - << "incorrect value for last_msg_.stec_sat_list[1].stec_coeff[2], " - "expected 65, is " - << last_msg_.stec_sat_list[1].stec_coeff[2]; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_coeff[3], 66) - << "incorrect value for last_msg_.stec_sat_list[1].stec_coeff[3], " - "expected 66, is " - << last_msg_.stec_sat_list[1].stec_coeff[3]; - EXPECT_EQ(last_msg_.stec_sat_list[1].stec_quality_indicator, 5) - << "incorrect value for " - "last_msg_.stec_sat_list[1].stec_quality_indicator, expected 5, is " - << last_msg_.stec_sat_list[1].stec_quality_indicator; - EXPECT_EQ(last_msg_.stec_sat_list[1].sv_id.constellation, 15) - << "incorrect value for last_msg_.stec_sat_list[1].sv_id.constellation, " - "expected 15, is " - << last_msg_.stec_sat_list[1].sv_id.constellation; - EXPECT_EQ(last_msg_.stec_sat_list[1].sv_id.satId, 31) - << "incorrect value for last_msg_.stec_sat_list[1].sv_id.satId, expected " - "31, is " - << last_msg_.stec_sat_list[1].sv_id.satId; - EXPECT_EQ(last_msg_.tile_id, 10) - << "incorrect value for last_msg_.tile_id, expected 10, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 1) - << "incorrect value for last_msg_.tile_set_id, expected 1, is " - << last_msg_.tile_set_id; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSsrStecCorrection, &info.test_msg_wrapped), + info.payload_len); } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[38]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_stec_correction_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 38); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 38), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrStecCorrection, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 38); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 38), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[38]; + + EXPECT_EQ(sbp_msg_ssr_stec_correction_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 38), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[38]; + + for (uint8_t i = 0; i < 38; i++) { + EXPECT_EQ( + sbp_msg_ssr_stec_correction_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_stec_correction_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_stec_correction_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 38); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSsrStecCorrection, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 38); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_stec_correction_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_stec_correction_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_stec_correction_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_ssr_stec_correction_t t{}; + return sbp_msg_ssr_stec_correction_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_ssr_stec_correction_t t{}; + t.n_sats = 1; + return sbp_msg_ssr_stec_correction_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_ssr_stec_correction_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_stec_correction_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrStecCorrection, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.num_msgs, greater.header.num_msgs); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.seq_num, greater.header.seq_num); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.sol_id, greater.header.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.tow, greater.header.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.time.wn, greater.header.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.header.update_interval, + greater.header.update_interval); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.n_sats, greater.n_sats); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_iod_atmo, greater.ssr_iod_atmo); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_coeff[0], + greater.stec_sat_list[0].stec_coeff[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_coeff[1], + greater.stec_sat_list[0].stec_coeff[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_coeff[2], + greater.stec_sat_list[0].stec_coeff[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_coeff[3], + greater.stec_sat_list[0].stec_coeff[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].stec_quality_indicator, + greater.stec_sat_list[0].stec_quality_indicator); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].sv_id.constellation, + greater.stec_sat_list[0].sv_id.constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[0].sv_id.satId, + greater.stec_sat_list[0].sv_id.satId); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_coeff[0], + greater.stec_sat_list[1].stec_coeff[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_coeff[1], + greater.stec_sat_list[1].stec_coeff[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_coeff[2], + greater.stec_sat_list[1].stec_coeff[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_coeff[3], + greater.stec_sat_list[1].stec_coeff[3]); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].stec_quality_indicator, + greater.stec_sat_list[1].stec_quality_indicator); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].sv_id.constellation, + greater.stec_sat_list[1].sv_id.constellation); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.stec_sat_list[1].sv_id.satId, + greater.stec_sat_list[1].sv_id.satId); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_stec_correction_t lesser = info.test_msg; + sbp_msg_ssr_stec_correction_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrStecCorrection); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_STEC_CORRECTION"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_stec_correction_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ssr_stec_correction_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_stec_correction, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ssr_stec_correction, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[38]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 38); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 38), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_stec_correction_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 38); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrStecCorrection, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrStecCorrection0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrStecCorrection, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinition.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinition.cc index 62178c44ac..0db8f71969 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinition.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinition.cc @@ -16,139 +16,672 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrTileDefinition0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrTileDefinition0 : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrTileDefinition0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrTileDefinition0() { + assign(test_msg_.bitmask, 1234567890); + assign(test_msg_.cols, 6); + assign(test_msg_.corner_nw_lat, 7354); + assign(test_msg_.corner_nw_lon, -22725); + assign(test_msg_.iod_atmo, 3); + assign(test_msg_.rows, 6); + assign(test_msg_.sol_id, 2); + assign(test_msg_.spacing_lat, 100); + assign(test_msg_.spacing_lon, 100); + assign(test_msg_.tile_id, 5); + assign(test_msg_.tile_set_id, 4); + assign(test_msg_.time.tow, 604799); + assign(test_msg_.time.wn, 2222); + assign(test_msg_.update_interval, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_tile_definition_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ssr_tile_definition_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrTileDefinition, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_tile_definition_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrTileDefinition); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_tile_definition, + sizeof(msg->ssr_tile_definition)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_tile_definition_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_tile_definition, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrTileDefinition); + info.sender_id = 0; + info.preamble = 0x55; + info.crc = 0x5ECC; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 33; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_tile_definition_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_tile_definition_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_tile_definition_t &lesser, + const sbp_msg_ssr_tile_definition_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ssr_tile_definition_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_tile_definition_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_tile_definition_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_tile_definition_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrTileDefinition, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrTileDefinition, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrTileDefinition, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrTileDefinition, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_ssr_MsgSsrTileDefinition0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_tile_definition_t test_msg_{}; + uint8_t encoded_frame_[33 + 8] = { 85, 248, 5, 0, 0, 33, 127, 58, 9, 0, 174, 8, 1, 2, 3, 4, 0, 5, 0, 186, 28, 59, 167, 100, 0, 100, 0, 6, 0, 6, 0, 210, 2, 150, 73, 0, 0, 0, 0, 204, 94, }; + uint8_t encoded_payload_[33] = { + 127, 58, 9, 0, 174, 8, 1, 2, 3, 4, 0, 5, 0, 186, 28, 59, 167, + 100, 0, 100, 0, 6, 0, 6, 0, 210, 2, 150, 73, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_tile_definition_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSsrTileDefinition, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrTileDefinition, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + + for (uint8_t i = 0; i < 33; i++) { + EXPECT_EQ( + sbp_msg_ssr_tile_definition_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSsrTileDefinition, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_t msg{}; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_t msg{}; - sbp_msg_ssr_tile_definition_t test_msg{}; - test_msg.bitmask = 1234567890; - test_msg.cols = 6; - test_msg.corner_nw_lat = 7354; - test_msg.corner_nw_lon = -22725; - test_msg.iod_atmo = 3; - test_msg.rows = 6; - test_msg.sol_id = 2; - test_msg.spacing_lat = 100; - test_msg.spacing_lon = 100; - test_msg.tile_id = 5; - test_msg.tile_set_id = 4; - test_msg.time.tow = 604799; - test_msg.time.wn = 2222; - test_msg.update_interval = 1; - - EXPECT_EQ(send_message(0, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 0); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.bitmask, 1234567890) - << "incorrect value for last_msg_.bitmask, expected 1234567890, is " - << last_msg_.bitmask; - EXPECT_EQ(last_msg_.cols, 6) - << "incorrect value for last_msg_.cols, expected 6, is " - << last_msg_.cols; - EXPECT_EQ(last_msg_.corner_nw_lat, 7354) - << "incorrect value for last_msg_.corner_nw_lat, expected 7354, is " - << last_msg_.corner_nw_lat; - EXPECT_EQ(last_msg_.corner_nw_lon, -22725) - << "incorrect value for last_msg_.corner_nw_lon, expected -22725, is " - << last_msg_.corner_nw_lon; - EXPECT_EQ(last_msg_.iod_atmo, 3) - << "incorrect value for last_msg_.iod_atmo, expected 3, is " - << last_msg_.iod_atmo; - EXPECT_EQ(last_msg_.rows, 6) - << "incorrect value for last_msg_.rows, expected 6, is " - << last_msg_.rows; - EXPECT_EQ(last_msg_.sol_id, 2) - << "incorrect value for last_msg_.sol_id, expected 2, is " - << last_msg_.sol_id; - EXPECT_EQ(last_msg_.spacing_lat, 100) - << "incorrect value for last_msg_.spacing_lat, expected 100, is " - << last_msg_.spacing_lat; - EXPECT_EQ(last_msg_.spacing_lon, 100) - << "incorrect value for last_msg_.spacing_lon, expected 100, is " - << last_msg_.spacing_lon; - EXPECT_EQ(last_msg_.tile_id, 5) - << "incorrect value for last_msg_.tile_id, expected 5, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 4) - << "incorrect value for last_msg_.tile_set_id, expected 4, is " - << last_msg_.tile_set_id; - EXPECT_EQ(last_msg_.time.tow, 604799) - << "incorrect value for last_msg_.time.tow, expected 604799, is " - << last_msg_.time.tow; - EXPECT_EQ(last_msg_.time.wn, 2222) - << "incorrect value for last_msg_.time.wn, expected 2222, is " - << last_msg_.time.wn; - EXPECT_EQ(last_msg_.update_interval, 1) - << "incorrect value for last_msg_.update_interval, expected 1, is " - << last_msg_.update_interval; + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_tile_definition_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSsrTileDefinition, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.bitmask, greater.bitmask); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.cols, greater.cols); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.corner_nw_lat, greater.corner_nw_lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.corner_nw_lon, greater.corner_nw_lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.iod_atmo, greater.iod_atmo); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.rows, greater.rows); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.sol_id, greater.sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.spacing_lat, greater.spacing_lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.spacing_lon, greater.spacing_lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.time.tow, greater.time.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.time.wn, greater.time.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_t greater = info.test_msg; + make_lesser_greater(lesser.update_interval, greater.update_interval); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrTileDefinition); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_TILE_DEFINITION"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_tile_definition_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ssr_tile_definition_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_tile_definition, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.ssr_tile_definition, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrTileDefinition, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinition0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrTileDefinition, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinitionDepB.cc b/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinitionDepB.cc index 9207819ac1..f53911b48c 100644 --- a/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinitionDepB.cc +++ b/c/test/cpp/auto_check_sbp_ssr_MsgSsrTileDefinitionDepB.cc @@ -16,122 +16,657 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_ssr_MsgSsrTileDefinitionDepB0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0 + : public ::testing::Test { public: - Test_auto_check_sbp_ssr_MsgSsrTileDefinitionDepB0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0() { + assign(test_msg_.bitmask, 1234567890); + assign(test_msg_.cols, 32768); + assign(test_msg_.corner_nw_lat, 1024); + assign(test_msg_.corner_nw_lon, 2048); + assign(test_msg_.rows, 16384); + assign(test_msg_.spacing_lat, 4096); + assign(test_msg_.spacing_lon, 8192); + assign(test_msg_.ssr_sol_id, 31); + assign(test_msg_.tile_id, 512); + assign(test_msg_.tile_set_id, 256); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_ssr_tile_definition_dep_b_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_tile_definition_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_ssr_tile_definition_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSsrTileDefinitionDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ssr_tile_definition_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSsrTileDefinitionDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ssr_tile_definition_dep_b, + sizeof(msg->ssr_tile_definition_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ssr_tile_definition_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ssr_tile_definition_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSsrTileDefinitionDepB); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x47D6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 25; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ssr_tile_definition_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ssr_tile_definition_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ssr_tile_definition_dep_b_t &lesser, + const sbp_msg_ssr_tile_definition_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ssr_tile_definition_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ssr_tile_definition_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrTileDefinitionDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSsrTileDefinitionDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSsrTileDefinitionDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSsrTileDefinitionDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ssr_tile_definition_dep_b_t test_msg_{}; + uint8_t encoded_frame_[25 + 8] = { 85, 247, 5, 66, 0, 25, 31, 0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32, 0, 64, 0, 128, 210, 2, 150, 73, 0, 0, 0, 0, 214, 71, }; + uint8_t encoded_payload_[25] = { + 31, 0, 1, 0, 2, 0, 4, 0, 8, 0, 16, 0, 32, + 0, 64, 0, 128, 210, 2, 150, 73, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgSsrTileDefinitionDepB, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[25]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 25); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 25), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ( + sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSsrTileDefinitionDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 25); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 25), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[25]; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 25), 0); +} +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[25]; + + for (uint8_t i = 0; i < 25; i++) { + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 25); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgSsrTileDefinitionDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 25); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_dep_b_t msg{}; - sbp_msg_ssr_tile_definition_dep_b_t test_msg{}; - test_msg.bitmask = 1234567890; - test_msg.cols = 32768; - test_msg.corner_nw_lat = 1024; - test_msg.corner_nw_lon = 2048; - test_msg.rows = 16384; - test_msg.spacing_lat = 4096; - test_msg.spacing_lon = 8192; - test_msg.ssr_sol_id = 31; - test_msg.tile_id = 512; - test_msg.tile_set_id = 256; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.bitmask, 1234567890) - << "incorrect value for last_msg_.bitmask, expected 1234567890, is " - << last_msg_.bitmask; - EXPECT_EQ(last_msg_.cols, 32768) - << "incorrect value for last_msg_.cols, expected 32768, is " - << last_msg_.cols; - EXPECT_EQ(last_msg_.corner_nw_lat, 1024) - << "incorrect value for last_msg_.corner_nw_lat, expected 1024, is " - << last_msg_.corner_nw_lat; - EXPECT_EQ(last_msg_.corner_nw_lon, 2048) - << "incorrect value for last_msg_.corner_nw_lon, expected 2048, is " - << last_msg_.corner_nw_lon; - EXPECT_EQ(last_msg_.rows, 16384) - << "incorrect value for last_msg_.rows, expected 16384, is " - << last_msg_.rows; - EXPECT_EQ(last_msg_.spacing_lat, 4096) - << "incorrect value for last_msg_.spacing_lat, expected 4096, is " - << last_msg_.spacing_lat; - EXPECT_EQ(last_msg_.spacing_lon, 8192) - << "incorrect value for last_msg_.spacing_lon, expected 8192, is " - << last_msg_.spacing_lon; - EXPECT_EQ(last_msg_.ssr_sol_id, 31) - << "incorrect value for last_msg_.ssr_sol_id, expected 31, is " - << last_msg_.ssr_sol_id; - EXPECT_EQ(last_msg_.tile_id, 512) - << "incorrect value for last_msg_.tile_id, expected 512, is " - << last_msg_.tile_id; - EXPECT_EQ(last_msg_.tile_set_id, 256) - << "incorrect value for last_msg_.tile_set_id, expected 256, is " - << last_msg_.tile_set_id; + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_decode(&info.encoded_payload[0], + i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ssr_tile_definition_dep_b_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgSsrTileDefinitionDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.bitmask, greater.bitmask); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.cols, greater.cols); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.corner_nw_lat, greater.corner_nw_lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.corner_nw_lon, greater.corner_nw_lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.rows, greater.rows); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.spacing_lat, greater.spacing_lat); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.spacing_lon, greater.spacing_lon); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.ssr_sol_id, greater.ssr_sol_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tile_id, greater.tile_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_ssr_tile_definition_dep_b_t lesser = info.test_msg; + sbp_msg_ssr_tile_definition_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.tile_set_id, greater.tile_set_id); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSsrTileDefinitionDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SSR_TILE_DEFINITION_DEP_B"); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ssr_tile_definition_dep_b_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_ssr_tile_definition_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.ssr_tile_definition_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.ssr_tile_definition_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[25]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 25); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 25), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ssr_tile_definition_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 25); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSsrTileDefinitionDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_ssr_MsgSsrTileDefinitionDepB0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSsrTileDefinitionDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgDgnssStatus.cc b/c/test/cpp/auto_check_sbp_system_MsgDgnssStatus.cc index 2402115447..eecc1b5293 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgDgnssStatus.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgDgnssStatus.cc @@ -16,103 +16,732 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgDgnssStatus0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgDgnssStatus0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgDgnssStatus0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } + Testauto_check_sbp_system_MsgDgnssStatus0() { + assign(test_msg_.flags, 0); + assign(test_msg_.latency, 50); + assign(test_msg_.num_signals, 12); - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; + size_t written; + EXPECT_TRUE(sbp_msg_dgnss_status_source_set(&test_msg_, "Skylark", false, + &written)); + EXPECT_EQ(written, strlen("Skylark")); + EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&test_msg_), 7); } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_dgnss_status_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_dgnss_status_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgDgnssStatus, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_dgnss_status_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgDgnssStatus); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->dgnss_status, + sizeof(msg->dgnss_status)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_dgnss_status_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.dgnss_status, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgDgnssStatus); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x1ca; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 11; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_dgnss_status_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_dgnss_status_t &lesser, + const sbp_msg_dgnss_status_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_dgnss_status_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_dgnss_status_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_dgnss_status_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_dgnss_status_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgDgnssStatus, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgDgnssStatus, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgDgnssStatus, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgDgnssStatus, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_dgnss_status_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_system_MsgDgnssStatus0, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_dgnss_status_t test_msg_{}; + uint8_t encoded_frame_[11 + 8] = { 85, 2, 255, 66, 0, 11, 0, 50, 0, 12, 83, 107, 121, 108, 97, 114, 107, 202, 1, }; + uint8_t encoded_payload_[11] = { + 0, 50, 0, 12, 83, 107, 121, 108, 97, 114, 107, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_dgnss_status_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgDgnssStatus, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_dgnss_status_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgDgnssStatus, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + EXPECT_EQ(sbp_msg_dgnss_status_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + + for (uint8_t i = 0; i < 11; i++) { + EXPECT_EQ(sbp_msg_dgnss_status_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dgnss_status_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_dgnss_status_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgDgnssStatus, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_dgnss_status_t msg{}; + + EXPECT_EQ(sbp_msg_dgnss_status_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_dgnss_status_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = SBP_MSG_DGNSS_STATUS_ENCODED_OVERHEAD; + // size_t overhead = []()->size_t{sbp_msg_dgnss_status_t t{}; return + // sbp_msg_dgnss_status_encoded_len(&t); }(); + if (i >= overhead) { + expected_return = SBP_OK; + } + + EXPECT_EQ( + sbp_msg_dgnss_status_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_dgnss_status_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_dgnss_status_t test_msg{}; - test_msg.flags = 0; - test_msg.latency = 50; - test_msg.num_signals = 12; +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgDgnssStatus, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_dgnss_status_t lesser = info.test_msg; + sbp_msg_dgnss_status_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_dgnss_status_t lesser = info.test_msg; + sbp_msg_dgnss_status_t greater = info.test_msg; + make_lesser_greater(lesser.latency, greater.latency); + comparison_tests(lesser, greater); + } + { + sbp_msg_dgnss_status_t lesser = info.test_msg; + sbp_msg_dgnss_status_t greater = info.test_msg; + make_lesser_greater(lesser.num_signals, greater.num_signals); + comparison_tests(lesser, greater); + } + { + sbp_msg_dgnss_status_t lesser = info.test_msg; + sbp_msg_dgnss_status_t greater = info.test_msg; + make_lesser_greater(lesser.source, greater.source); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgDgnssStatus); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_DGNSS_STATUS"); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_dgnss_status_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_dgnss_status_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.dgnss_status, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.dgnss_status, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[11]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 11); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 11), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_dgnss_status_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 11); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgDgnssStatus, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgDgnssStatus, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_system_MsgDgnssStatus0_source + : public Testauto_check_sbp_system_MsgDgnssStatus0 {}; + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, StringInit) { + sbp_msg_dgnss_status_t t{}; + sbp_msg_dgnss_status_source_init(&t); + EXPECT_TRUE(sbp_msg_dgnss_status_source_valid(&t)); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, IsValid) { + sbp_msg_dgnss_status_t t{}; size_t written; - EXPECT_TRUE( - sbp_msg_dgnss_status_source_set(&test_msg, "Skylark", false, &written)); + EXPECT_TRUE(sbp_msg_dgnss_status_source_set(&t, "Skylark", false, &written)); EXPECT_EQ(written, strlen("Skylark")); - EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&test_msg), 7); + EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&t), 7); + EXPECT_TRUE(sbp_msg_dgnss_status_source_valid(&t)); +} - EXPECT_EQ(send_message(66, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, SpaceRemaining) { + sbp_msg_dgnss_status_t t{}; + size_t empty_space_remaining = + sbp_msg_dgnss_status_source_space_remaining(&t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + size_t written; + EXPECT_TRUE(sbp_msg_dgnss_status_source_set(&t, "Skylark", false, &written)); + EXPECT_EQ(written, strlen("Skylark")); + EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&t), 7); + size_t assigned_space_remaining = + sbp_msg_dgnss_status_source_space_remaining(&t); + EXPECT_LT(assigned_space_remaining, empty_space_remaining); +} - while (dummy_rd_ < dummy_wr_) { - process(); - } +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, SetRaw) { + auto info = get_test_msg_info(); + sbp_msg_dgnss_status_t t{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.latency, 50) - << "incorrect value for last_msg_.latency, expected 50, is " - << last_msg_.latency; - EXPECT_EQ(last_msg_.num_signals, 12) - << "incorrect value for last_msg_.num_signals, expected 12, is " - << last_msg_.num_signals; - - EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&last_msg_), 7); - EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&last_msg_), "Skylark"); + size_t nwritten{}; + + EXPECT_TRUE(sbp_msg_dgnss_status_source_set_raw( + &t, info.test_msg.source.data, + sbp_msg_dgnss_status_source_strlen(&info.test_msg), false, &nwritten)); + EXPECT_EQ(sbp_msg_dgnss_status_source_encoded_len(&info.test_msg), + sbp_msg_dgnss_status_source_encoded_len(&t)); } + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, Set) { + sbp_msg_dgnss_status_t t{}; + size_t nwritten{}; + const char *text = "Skylark"; + + EXPECT_TRUE(sbp_msg_dgnss_status_source_set(&t, text, false, &nwritten)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), text); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, Printf) { + sbp_msg_dgnss_status_t t{}; + size_t nwritten{}; + const char *text = "Skylark"; + + EXPECT_TRUE( + sbp_msg_dgnss_status_source_printf(&t, false, &nwritten, "%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), text); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, Vprintf) { + sbp_msg_dgnss_status_t t{}; + size_t nwritten{}; + const char *text = "Skylark"; + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = + sbp_msg_dgnss_status_source_vprintf(&t, false, &nwritten, format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", text)); + EXPECT_EQ(nwritten, strlen(text)); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), text); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, AppendPrintf) { + sbp_msg_dgnss_status_t t{}; + size_t nwritten{}; + char part1[] = "Skylark"; + char part2[] = "Skylark"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_dgnss_status_source_printf(&t, false, &nwritten, "%s", + &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), &part1[0]); + + EXPECT_TRUE(sbp_msg_dgnss_status_source_append_printf(&t, false, &nwritten, + "%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), "Skylark"); +} + +TEST_F(Testauto_check_sbp_system_MsgDgnssStatus0_source, AppendVprintf) { + sbp_msg_dgnss_status_t t{}; + size_t nwritten{}; + char part1[] = "Skylark"; + char part2[] = "Skylark"; + + part1[1] = 0; + + EXPECT_TRUE(sbp_msg_dgnss_status_source_printf(&t, false, &nwritten, "%s", + &part1[0])); + EXPECT_EQ(nwritten, 1); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), &part1[0]); + + auto lambda = [&t, &nwritten](const char *format, ...) -> bool { + va_list ap; + va_start(ap, format); + bool ret = sbp_msg_dgnss_status_source_append_vprintf(&t, false, &nwritten, + format, ap); + va_end(ap); + return ret; + }; + + EXPECT_TRUE(lambda("%s", &part2[1])); + EXPECT_EQ(nwritten, strlen(&part2[1])); + EXPECT_STREQ(sbp_msg_dgnss_status_source_get(&t), "Skylark"); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgGroupMeta.cc b/c/test/cpp/auto_check_sbp_system_MsgGroupMeta.cc index 492da6ceb0..8a6818551c 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgGroupMeta.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgGroupMeta.cc @@ -16,267 +16,1320 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgGroupMeta0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgGroupMeta0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgGroupMeta0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgGroupMeta0() { + assign(test_msg_.flags, 2); + assign(test_msg_.group_id, 1); + + assign(test_msg_.group_msgs[0], 65290); + + assign(test_msg_.group_msgs[1], 522); + + assign(test_msg_.group_msgs[2], 65282); + assign(test_msg_.n_group_msgs, 3); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_group_meta_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_group_meta_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGroupMeta, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_group_meta_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGroupMeta); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->group_meta, sizeof(msg->group_meta)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_group_meta_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.group_meta, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGroupMeta); + info.sender_id = 61166; + info.preamble = 0x55; + info.crc = 0xe02; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 9; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_group_meta_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_group_meta_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_group_meta_t &lesser, + const sbp_msg_group_meta_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); -TEST_F(Test_auto_check_sbp_system_MsgGroupMeta0, Test) { - uint8_t encoded_frame[] = { + EXPECT_EQ(sbp_msg_group_meta_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_group_meta_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_group_meta_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_group_meta_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_group_meta_t test_msg_{}; + uint8_t encoded_frame_[9 + 8] = { 85, 10, 255, 238, 238, 9, 1, 2, 3, 10, 255, 10, 2, 2, 255, 2, 14, }; + uint8_t encoded_payload_[9] = { + 1, 2, 3, 10, 255, 10, 2, 2, 255, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_group_meta_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGroupMeta, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_group_meta_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGroupMeta, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + EXPECT_EQ( + sbp_msg_group_meta_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + for (uint8_t i = 0; i < 9; i++) { + EXPECT_EQ(sbp_msg_group_meta_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_group_meta_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGroupMeta, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + + EXPECT_EQ(sbp_msg_group_meta_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_group_meta_t t{}; + return sbp_msg_group_meta_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_group_meta_t t{}; + t.n_group_msgs = 1; + return sbp_msg_group_meta_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_group_meta_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} - sbp_msg_group_meta_t test_msg{}; - test_msg.flags = 2; - test_msg.group_id = 1; - - test_msg.group_msgs[0] = 65290; - - test_msg.group_msgs[1] = 522; - - test_msg.group_msgs[2] = 65282; - test_msg.n_group_msgs = 3; - - EXPECT_EQ(send_message(61166, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 61166); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 2) - << "incorrect value for last_msg_.flags, expected 2, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.group_id, 1) - << "incorrect value for last_msg_.group_id, expected 1, is " - << last_msg_.group_id; - EXPECT_EQ(last_msg_.group_msgs[0], 65290) - << "incorrect value for last_msg_.group_msgs[0], expected 65290, is " - << last_msg_.group_msgs[0]; - EXPECT_EQ(last_msg_.group_msgs[1], 522) - << "incorrect value for last_msg_.group_msgs[1], expected 522, is " - << last_msg_.group_msgs[1]; - EXPECT_EQ(last_msg_.group_msgs[2], 65282) - << "incorrect value for last_msg_.group_msgs[2], expected 65282, is " - << last_msg_.group_msgs[2]; - EXPECT_EQ(last_msg_.n_group_msgs, 3) - << "incorrect value for last_msg_.n_group_msgs, expected 3, is " - << last_msg_.n_group_msgs; -} -class Test_auto_check_sbp_system_MsgGroupMeta1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_group_meta_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGroupMeta, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_id, greater.group_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[0], greater.group_msgs[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[1], greater.group_msgs[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[2], greater.group_msgs[2]); + comparison_tests(lesser, greater); + } + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.n_group_msgs, greater.n_group_msgs); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGroupMeta); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GROUP_META"); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_group_meta_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_group_meta_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.group_meta, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.group_meta, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGroupMeta, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGroupMeta, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_system_MsgGroupMeta1 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgGroupMeta1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgGroupMeta1() { + assign(test_msg_.flags, 1); + assign(test_msg_.group_id, 1); + + assign(test_msg_.group_msgs[0], 258); + + assign(test_msg_.group_msgs[1], 259); + + assign(test_msg_.group_msgs[2], 522); + + assign(test_msg_.group_msgs[3], 529); + + assign(test_msg_.group_msgs[4], 521); + + assign(test_msg_.group_msgs[5], 532); + + assign(test_msg_.group_msgs[6], 526); + + assign(test_msg_.group_msgs[7], 530); + + assign(test_msg_.group_msgs[8], 525); + + assign(test_msg_.group_msgs[9], 533); + + assign(test_msg_.group_msgs[10], 545); + + assign(test_msg_.group_msgs[11], 65283); + + assign(test_msg_.group_msgs[12], 65286); + + assign(test_msg_.group_msgs[13], 65294); + assign(test_msg_.n_group_msgs, 14); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_group_meta_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_group_meta_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgGroupMeta, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_group_meta_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgGroupMeta); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->group_meta, sizeof(msg->group_meta)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_group_meta_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.group_meta, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgGroupMeta); + info.sender_id = 789; + info.preamble = 0x55; + info.crc = 0x9a52; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 31; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_group_meta_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_group_meta_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_group_meta_t &lesser, + const sbp_msg_group_meta_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_group_meta_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_group_meta_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_group_meta_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_group_meta_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgGroupMeta, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_system_MsgGroupMeta1, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_group_meta_t test_msg_{}; + uint8_t encoded_frame_[31 + 8] = { 85, 10, 255, 21, 3, 31, 1, 1, 14, 2, 1, 3, 1, 10, 2, 17, 2, 9, 2, 20, 2, 14, 2, 18, 2, 13, 2, 21, 2, 33, 2, 3, 255, 6, 255, 14, 255, 82, 154, }; + uint8_t encoded_payload_[31] = { + 1, 1, 14, 2, 1, 3, 1, 10, 2, 17, 2, 9, 2, 20, 2, 14, + 2, 18, 2, 13, 2, 21, 2, 33, 2, 3, 255, 6, 255, 14, 255, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_group_meta_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgGroupMeta, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_group_meta_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgGroupMeta, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + EXPECT_EQ( + sbp_msg_group_meta_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + + for (uint8_t i = 0; i < 31; i++) { + EXPECT_EQ(sbp_msg_group_meta_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_group_meta_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgGroupMeta, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + + EXPECT_EQ(sbp_msg_group_meta_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_group_meta_t t{}; + return sbp_msg_group_meta_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_group_meta_t t{}; + t.n_group_msgs = 1; + return sbp_msg_group_meta_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ( + sbp_msg_group_meta_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_group_meta_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgGroupMeta, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_id, greater.group_id); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[0], greater.group_msgs[0]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[1], greater.group_msgs[1]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[2], greater.group_msgs[2]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[3], greater.group_msgs[3]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[4], greater.group_msgs[4]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[5], greater.group_msgs[5]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[6], greater.group_msgs[6]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[7], greater.group_msgs[7]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[8], greater.group_msgs[8]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[9], greater.group_msgs[9]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[10], greater.group_msgs[10]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[11], greater.group_msgs[11]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[12], greater.group_msgs[12]); + comparison_tests(lesser, greater); + } + + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.group_msgs[13], greater.group_msgs[13]); + comparison_tests(lesser, greater); + } + { + sbp_msg_group_meta_t lesser = info.test_msg; + sbp_msg_group_meta_t greater = info.test_msg; + make_lesser_greater(lesser.n_group_msgs, greater.n_group_msgs); + comparison_tests(lesser, greater); + } +} - sbp_msg_group_meta_t test_msg{}; - test_msg.flags = 1; - test_msg.group_id = 1; - - test_msg.group_msgs[0] = 258; - - test_msg.group_msgs[1] = 259; - - test_msg.group_msgs[2] = 522; - - test_msg.group_msgs[3] = 529; - - test_msg.group_msgs[4] = 521; - - test_msg.group_msgs[5] = 532; - - test_msg.group_msgs[6] = 526; - - test_msg.group_msgs[7] = 530; - - test_msg.group_msgs[8] = 525; - - test_msg.group_msgs[9] = 533; - - test_msg.group_msgs[10] = 545; - - test_msg.group_msgs[11] = 65283; - - test_msg.group_msgs[12] = 65286; - - test_msg.group_msgs[13] = 65294; - test_msg.n_group_msgs = 14; - - EXPECT_EQ(send_message(789, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 789); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.group_id, 1) - << "incorrect value for last_msg_.group_id, expected 1, is " - << last_msg_.group_id; - EXPECT_EQ(last_msg_.group_msgs[0], 258) - << "incorrect value for last_msg_.group_msgs[0], expected 258, is " - << last_msg_.group_msgs[0]; - EXPECT_EQ(last_msg_.group_msgs[1], 259) - << "incorrect value for last_msg_.group_msgs[1], expected 259, is " - << last_msg_.group_msgs[1]; - EXPECT_EQ(last_msg_.group_msgs[2], 522) - << "incorrect value for last_msg_.group_msgs[2], expected 522, is " - << last_msg_.group_msgs[2]; - EXPECT_EQ(last_msg_.group_msgs[3], 529) - << "incorrect value for last_msg_.group_msgs[3], expected 529, is " - << last_msg_.group_msgs[3]; - EXPECT_EQ(last_msg_.group_msgs[4], 521) - << "incorrect value for last_msg_.group_msgs[4], expected 521, is " - << last_msg_.group_msgs[4]; - EXPECT_EQ(last_msg_.group_msgs[5], 532) - << "incorrect value for last_msg_.group_msgs[5], expected 532, is " - << last_msg_.group_msgs[5]; - EXPECT_EQ(last_msg_.group_msgs[6], 526) - << "incorrect value for last_msg_.group_msgs[6], expected 526, is " - << last_msg_.group_msgs[6]; - EXPECT_EQ(last_msg_.group_msgs[7], 530) - << "incorrect value for last_msg_.group_msgs[7], expected 530, is " - << last_msg_.group_msgs[7]; - EXPECT_EQ(last_msg_.group_msgs[8], 525) - << "incorrect value for last_msg_.group_msgs[8], expected 525, is " - << last_msg_.group_msgs[8]; - EXPECT_EQ(last_msg_.group_msgs[9], 533) - << "incorrect value for last_msg_.group_msgs[9], expected 533, is " - << last_msg_.group_msgs[9]; - EXPECT_EQ(last_msg_.group_msgs[10], 545) - << "incorrect value for last_msg_.group_msgs[10], expected 545, is " - << last_msg_.group_msgs[10]; - EXPECT_EQ(last_msg_.group_msgs[11], 65283) - << "incorrect value for last_msg_.group_msgs[11], expected 65283, is " - << last_msg_.group_msgs[11]; - EXPECT_EQ(last_msg_.group_msgs[12], 65286) - << "incorrect value for last_msg_.group_msgs[12], expected 65286, is " - << last_msg_.group_msgs[12]; - EXPECT_EQ(last_msg_.group_msgs[13], 65294) - << "incorrect value for last_msg_.group_msgs[13], expected 65294, is " - << last_msg_.group_msgs[13]; - EXPECT_EQ(last_msg_.n_group_msgs, 14) - << "incorrect value for last_msg_.n_group_msgs, expected 14, is " - << last_msg_.n_group_msgs; +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgGroupMeta); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_GROUP_META"); } + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_group_meta_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_group_meta_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.group_meta, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.group_meta, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[31]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 31); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 31), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_group_meta_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 31); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgGroupMeta, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgGroupMeta1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgGroupMeta, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgHeartbeat.cc b/c/test/cpp/auto_check_sbp_system_MsgHeartbeat.cc index ff8cfc339b..48d302516f 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgHeartbeat.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgHeartbeat.cc @@ -16,164 +16,1104 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgHeartbeat0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgHeartbeat0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgHeartbeat0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgHeartbeat0() { assign(test_msg_.flags, 12800); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_heartbeat_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_heartbeat_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgHeartbeat, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_heartbeat_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgHeartbeat); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->heartbeat, sizeof(msg->heartbeat)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_heartbeat_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.heartbeat, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgHeartbeat); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xd8f9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_heartbeat_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_heartbeat_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_heartbeat_t &lesser, + const sbp_msg_heartbeat_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_heartbeat_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_heartbeat_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_heartbeat_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_heartbeat_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); -TEST_F(Test_auto_check_sbp_system_MsgHeartbeat0, Test) { - uint8_t encoded_frame[] = { + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_heartbeat_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 255, 255, 246, 215, 4, 0, 50, 0, 0, 249, 216, }; + uint8_t encoded_payload_[4] = { + 0, + 50, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_heartbeat_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgHeartbeat, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_heartbeat_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgHeartbeat, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_heartbeat_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_heartbeat_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_heartbeat_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgHeartbeat, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + + EXPECT_EQ(sbp_msg_heartbeat_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_heartbeat_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_heartbeat_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgHeartbeat, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_heartbeat_t lesser = info.test_msg; + sbp_msg_heartbeat_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgHeartbeat); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_HEARTBEAT"); +} - sbp_msg_heartbeat_t test_msg{}; - test_msg.flags = 12800; +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + const sbp_msg_heartbeat_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_heartbeat_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.heartbeat, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.heartbeat, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 12800) - << "incorrect value for last_msg_.flags, expected 12800, is " - << last_msg_.flags; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgHeartbeat, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgHeartbeat, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } -class Test_auto_check_sbp_system_MsgHeartbeat1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + +class Testauto_check_sbp_system_MsgHeartbeat1 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgHeartbeat1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgHeartbeat1() { assign(test_msg_.flags, 0); } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_heartbeat_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_heartbeat_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgHeartbeat, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_heartbeat_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgHeartbeat); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->heartbeat, sizeof(msg->heartbeat)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_heartbeat_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.heartbeat, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgHeartbeat); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x3942; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_heartbeat_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_heartbeat_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_heartbeat_t &lesser, + const sbp_msg_heartbeat_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_heartbeat_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_heartbeat_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_heartbeat_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_heartbeat_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgHeartbeat, &wrapped_greater, &wrapped_lesser), 0); -TEST_F(Test_auto_check_sbp_system_MsgHeartbeat1, Test) { - uint8_t encoded_frame[] = { + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_heartbeat_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 255, 255, 195, 4, 4, 0, 0, 0, 0, 66, 57, }; + uint8_t encoded_payload_[4] = { + 0, + 0, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_heartbeat_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgHeartbeat, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_heartbeat_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); - sbp_msg_heartbeat_t test_msg{}; - test_msg.flags = 0; + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgHeartbeat, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ( + sbp_msg_heartbeat_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; - while (dummy_rd_ < dummy_wr_) { - process(); + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_heartbeat_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_heartbeat_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgHeartbeat, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; + EXPECT_EQ(sbp_msg_heartbeat_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); } +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_heartbeat_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_heartbeat_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgHeartbeat, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_heartbeat_t lesser = info.test_msg; + sbp_msg_heartbeat_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgHeartbeat); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_HEARTBEAT"); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_heartbeat_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_heartbeat_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.heartbeat, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.heartbeat, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_heartbeat_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgHeartbeat, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgHeartbeat1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgHeartbeat, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgInsStatus.cc b/c/test/cpp/auto_check_sbp_system_MsgInsStatus.cc index c18285413a..b1c4c9bcaa 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgInsStatus.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgInsStatus.cc @@ -16,85 +16,563 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgInsStatus0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgInsStatus0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgInsStatus0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_system_MsgInsStatus0() { + assign(test_msg_.flags, 536870921); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ins_status_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ins_status_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgInsStatus, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ins_status_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgInsStatus); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ins_status, sizeof(msg->ins_status)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ins_status_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ins_status, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgInsStatus); + info.sender_id = 789; + info.preamble = 0x55; + info.crc = 0x6724; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ins_status_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_ins_status_t &lesser, + const sbp_msg_ins_status_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ins_status_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ins_status_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ins_status_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ins_status_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgInsStatus, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgInsStatus, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgInsStatus, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgInsStatus, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_ins_status_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_system_MsgInsStatus0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_ins_status_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 3, 255, 21, 3, 4, 9, 0, 0, 32, 36, 103, }; + uint8_t encoded_payload_[4] = { + 9, + 0, + 0, + 32, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ins_status_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgInsStatus, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ins_status_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgInsStatus, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_ins_status_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_ins_status_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} - sbp_msg_ins_status_t test_msg{}; - test_msg.flags = 536870921; +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ins_status_t msg{}; + uint8_t n_read; - EXPECT_EQ(send_message(789, test_msg), SBP_OK); + EXPECT_EQ(sbp_msg_ins_status_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgInsStatus, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ins_status_t msg{}; + + EXPECT_EQ(sbp_msg_ins_status_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ins_status_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; - while (dummy_rd_ < dummy_wr_) { - process(); + EXPECT_EQ( + sbp_msg_ins_status_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); } +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ins_status_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgInsStatus, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ins_status_t lesser = info.test_msg; + sbp_msg_ins_status_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgInsStatus); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_INS_STATUS"); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ins_status_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ins_status_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ins_status, info.test_msg); - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 789); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 536870921) - << "incorrect value for last_msg_.flags, expected 536870921, is " - << last_msg_.flags; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ins_status, info.test_msg); } + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ins_status_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgInsStatus, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsStatus0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgInsStatus, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgInsUpdates.cc b/c/test/cpp/auto_check_sbp_system_MsgInsUpdates.cc index 52745133bc..12506d2c6e 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgInsUpdates.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgInsUpdates.cc @@ -16,108 +16,604 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgInsUpdates0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgInsUpdates0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgInsUpdates0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgInsUpdates0() { + assign(test_msg_.gnsspos, 0); + assign(test_msg_.gnssvel, 0); + assign(test_msg_.nhc, 0); + assign(test_msg_.speed, 0); + assign(test_msg_.tow, 504489300); + assign(test_msg_.wheelticks, 0); + assign(test_msg_.zerovel, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_ins_updates_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_ins_updates_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgInsUpdates, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_ins_updates_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgInsUpdates); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->ins_updates, sizeof(msg->ins_updates)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_ins_updates_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.ins_updates, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgInsUpdates); + info.sender_id = 789; + info.preamble = 0x55; + info.crc = 0x3f51; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 10; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_ins_updates_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_ins_updates_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_ins_updates_t &lesser, + const sbp_msg_ins_updates_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_ins_updates_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_ins_updates_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_ins_updates_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_ins_updates_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgInsUpdates, &wrapped_lesser, &wrapped_lesser), 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgInsUpdates, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgInsUpdates, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgInsUpdates, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_system_MsgInsUpdates0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_ins_updates_t test_msg_{}; + uint8_t encoded_frame_[10 + 8] = { 85, 6, 255, 21, 3, 10, 84, 229, 17, 30, 0, 0, 0, 0, 0, 0, 81, 63, }; + uint8_t encoded_payload_[10] = { + 84, 229, 17, 30, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_ins_updates_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgInsUpdates, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_ins_updates_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgInsUpdates, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[10]; - sbp_msg_ins_updates_t test_msg{}; - test_msg.gnsspos = 0; - test_msg.gnssvel = 0; - test_msg.nhc = 0; - test_msg.speed = 0; - test_msg.tow = 504489300; - test_msg.wheelticks = 0; - test_msg.zerovel = 0; - - EXPECT_EQ(send_message(789, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 789); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.gnsspos, 0) - << "incorrect value for last_msg_.gnsspos, expected 0, is " - << last_msg_.gnsspos; - EXPECT_EQ(last_msg_.gnssvel, 0) - << "incorrect value for last_msg_.gnssvel, expected 0, is " - << last_msg_.gnssvel; - EXPECT_EQ(last_msg_.nhc, 0) - << "incorrect value for last_msg_.nhc, expected 0, is " << last_msg_.nhc; - EXPECT_EQ(last_msg_.speed, 0) - << "incorrect value for last_msg_.speed, expected 0, is " - << last_msg_.speed; - EXPECT_EQ(last_msg_.tow, 504489300) - << "incorrect value for last_msg_.tow, expected 504489300, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wheelticks, 0) - << "incorrect value for last_msg_.wheelticks, expected 0, is " - << last_msg_.wheelticks; - EXPECT_EQ(last_msg_.zerovel, 0) - << "incorrect value for last_msg_.zerovel, expected 0, is " - << last_msg_.zerovel; + EXPECT_EQ( + sbp_msg_ins_updates_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); } +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + + for (uint8_t i = 0; i < 10; i++) { + EXPECT_EQ(sbp_msg_ins_updates_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ins_updates_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_ins_updates_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgInsUpdates, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_ins_updates_t msg{}; + + EXPECT_EQ(sbp_msg_ins_updates_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_ins_updates_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_ins_updates_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_ins_updates_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgInsUpdates, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.gnsspos, greater.gnsspos); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.gnssvel, greater.gnssvel); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.nhc, greater.nhc); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.speed, greater.speed); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.wheelticks, greater.wheelticks); + comparison_tests(lesser, greater); + } + { + sbp_msg_ins_updates_t lesser = info.test_msg; + sbp_msg_ins_updates_t greater = info.test_msg; + make_lesser_greater(lesser.zerovel, greater.zerovel); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgInsUpdates); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_INS_UPDATES"); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_ins_updates_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_ins_updates_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.ins_updates, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.ins_updates, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[10]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 10); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 10), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_ins_updates_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 10); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgInsUpdates, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgInsUpdates0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgInsUpdates, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgSensorAidEvent.cc b/c/test/cpp/auto_check_sbp_system_MsgSensorAidEvent.cc index f68cae220a..9fa1f2666a 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgSensorAidEvent.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgSensorAidEvent.cc @@ -16,114 +16,626 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgSensorAidEvent0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgSensorAidEvent0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgSensorAidEvent0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgSensorAidEvent0() { + assign(test_msg_.flags, 0); + assign(test_msg_.n_accepted_meas, 0); + assign(test_msg_.n_attempted_meas, 0); + assign(test_msg_.n_available_meas, 0); + assign(test_msg_.sensor_id, 0); + assign(test_msg_.sensor_state, 0); + assign(test_msg_.sensor_type, 0); + assign(test_msg_.time, 326825520); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_sensor_aid_event_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_sensor_aid_event_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgSensorAidEvent, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_sensor_aid_event_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgSensorAidEvent); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->sensor_aid_event, + sizeof(msg->sensor_aid_event)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_sensor_aid_event_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.sensor_aid_event, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgSensorAidEvent); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0xEC21; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 15; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_sensor_aid_event_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_sensor_aid_event_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_sensor_aid_event_t &lesser, + const sbp_msg_sensor_aid_event_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_sensor_aid_event_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_sensor_aid_event_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_sensor_aid_event_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_sensor_aid_event_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgSensorAidEvent, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgSensorAidEvent, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgSensorAidEvent, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgSensorAidEvent, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_system_MsgSensorAidEvent0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_sensor_aid_event_t test_msg_{}; + uint8_t encoded_frame_[15 + 8] = { 85, 9, 255, 211, 136, 15, 48, 246, 122, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 236, }; + uint8_t encoded_payload_[15] = { + 48, 246, 122, 19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_sensor_aid_event_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgSensorAidEvent, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_sensor_aid_event_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgSensorAidEvent, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + + EXPECT_EQ(sbp_msg_sensor_aid_event_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + + for (uint8_t i = 0; i < 15; i++) { + EXPECT_EQ( + sbp_msg_sensor_aid_event_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sensor_aid_event_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_sensor_aid_event_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgSensorAidEvent, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} - sbp_msg_sensor_aid_event_t test_msg{}; - test_msg.flags = 0; - test_msg.n_accepted_meas = 0; - test_msg.n_attempted_meas = 0; - test_msg.n_available_meas = 0; - test_msg.sensor_id = 0; - test_msg.sensor_state = 0; - test_msg.sensor_type = 0; - test_msg.time = 326825520; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 0) - << "incorrect value for last_msg_.flags, expected 0, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.n_accepted_meas, 0) - << "incorrect value for last_msg_.n_accepted_meas, expected 0, is " - << last_msg_.n_accepted_meas; - EXPECT_EQ(last_msg_.n_attempted_meas, 0) - << "incorrect value for last_msg_.n_attempted_meas, expected 0, is " - << last_msg_.n_attempted_meas; - EXPECT_EQ(last_msg_.n_available_meas, 0) - << "incorrect value for last_msg_.n_available_meas, expected 0, is " - << last_msg_.n_available_meas; - EXPECT_EQ(last_msg_.sensor_id, 0) - << "incorrect value for last_msg_.sensor_id, expected 0, is " - << last_msg_.sensor_id; - EXPECT_EQ(last_msg_.sensor_state, 0) - << "incorrect value for last_msg_.sensor_state, expected 0, is " - << last_msg_.sensor_state; - EXPECT_EQ(last_msg_.sensor_type, 0) - << "incorrect value for last_msg_.sensor_type, expected 0, is " - << last_msg_.sensor_type; - EXPECT_EQ(last_msg_.time, 326825520) - << "incorrect value for last_msg_.time, expected 326825520, is " - << last_msg_.time; +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_sensor_aid_event_t msg{}; + + EXPECT_EQ(sbp_msg_sensor_aid_event_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_sensor_aid_event_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_sensor_aid_event_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_sensor_aid_event_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgSensorAidEvent, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.n_accepted_meas, greater.n_accepted_meas); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.n_attempted_meas, greater.n_attempted_meas); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.n_available_meas, greater.n_available_meas); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.sensor_id, greater.sensor_id); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.sensor_state, greater.sensor_state); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.sensor_type, greater.sensor_type); + comparison_tests(lesser, greater); + } + { + sbp_msg_sensor_aid_event_t lesser = info.test_msg; + sbp_msg_sensor_aid_event_t greater = info.test_msg; + make_lesser_greater(lesser.time, greater.time); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgSensorAidEvent); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_SENSOR_AID_EVENT"); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_sensor_aid_event_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_sensor_aid_event_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); } + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.sensor_aid_event, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.sensor_aid_event, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[15]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 15); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 15), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_sensor_aid_event_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 15); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgSensorAidEvent, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgSensorAidEvent0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgSensorAidEvent, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgStartup.cc b/c/test/cpp/auto_check_sbp_system_MsgStartup.cc index 8661409408..1cd879219d 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgStartup.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgStartup.cc @@ -16,180 +16,1132 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgStartup0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgStartup0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgStartup0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgStartup0() { + assign(test_msg_.cause, 0); + assign(test_msg_.reserved, 0); + assign(test_msg_.startup_type, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_startup_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_startup_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgStartup, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_startup_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgStartup); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->startup, sizeof(msg->startup)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_startup_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.startup, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgStartup); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0xa046; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_startup_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_startup_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_startup_t &lesser, + const sbp_msg_startup_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_startup_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_startup_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_startup_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_startup_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgStartup, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgStartup, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgStartup, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgStartup, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } -TEST_F(Test_auto_check_sbp_system_MsgStartup0, Test) { - uint8_t encoded_frame[] = { + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_startup_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 0, 255, 66, 0, 4, 0, 0, 0, 0, 70, 160, }; + uint8_t encoded_payload_[4] = { + 0, + 0, + 0, + 0, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgStartup0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_startup_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgStartup, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_startup_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgStartup, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_startup_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_system_MsgStartup0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_startup_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_startup_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgStartup, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + + EXPECT_EQ(sbp_msg_startup_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgStartup0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_startup_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_startup_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgStartup, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.cause, greater.cause); + comparison_tests(lesser, greater); + } + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.reserved, greater.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.startup_type, greater.startup_type); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgStartup); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_STARTUP"); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_startup_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_startup_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.startup, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.startup, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgStartup, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_startup_t test_msg{}; - test_msg.cause = 0; - test_msg.reserved = 0; - test_msg.startup_type = 0; - - EXPECT_EQ(send_message(66, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cause, 0) - << "incorrect value for last_msg_.cause, expected 0, is " - << last_msg_.cause; - EXPECT_EQ(last_msg_.reserved, 0) - << "incorrect value for last_msg_.reserved, expected 0, is " - << last_msg_.reserved; - EXPECT_EQ(last_msg_.startup_type, 0) - << "incorrect value for last_msg_.startup_type, expected 0, is " - << last_msg_.startup_type; -} -class Test_auto_check_sbp_system_MsgStartup1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_system_MsgStartup0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgStartup, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_system_MsgStartup1 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgStartup1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgStartup1() { + assign(test_msg_.cause, 0); + assign(test_msg_.reserved, 0); + assign(test_msg_.startup_type, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_startup_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_startup_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgStartup, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_startup_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgStartup); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->startup, sizeof(msg->startup)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_startup_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.startup, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgStartup); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xb57f; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 4; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_startup_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_startup_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_startup_t &lesser, + const sbp_msg_startup_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_startup_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_startup_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_startup_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_startup_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgStartup, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgStartup, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE(sbp_message_cmp(SbpMsgStartup, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgStartup, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_system_MsgStartup1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_startup_t test_msg_{}; + uint8_t encoded_frame_[4 + 8] = { 85, 0, 255, 195, 4, 4, 0, 0, 0, 0, 127, 181, }; + uint8_t encoded_payload_[4] = { + 0, + 0, + 0, + 0, + }; +}; - sbp_msg_startup_t test_msg{}; - test_msg.cause = 0; - test_msg.reserved = 0; - test_msg.startup_type = 0; +TEST_F(Testauto_check_sbp_system_MsgStartup1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_startup_encoded_len(&info.test_msg), info.payload_len); - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); + EXPECT_EQ(sbp_message_encoded_len(SbpMsgStartup, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ( + sbp_msg_startup_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgStartup, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_system_MsgStartup1, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + EXPECT_EQ( + sbp_msg_startup_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} +TEST_F(Testauto_check_sbp_system_MsgStartup1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + + for (uint8_t i = 0; i < 4; i++) { + EXPECT_EQ(sbp_msg_startup_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); } +} - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.cause, 0) - << "incorrect value for last_msg_.cause, expected 0, is " - << last_msg_.cause; - EXPECT_EQ(last_msg_.reserved, 0) - << "incorrect value for last_msg_.reserved, expected 0, is " - << last_msg_.reserved; - EXPECT_EQ(last_msg_.startup_type, 0) - << "incorrect value for last_msg_.startup_type, expected 0, is " - << last_msg_.startup_type; +TEST_F(Testauto_check_sbp_system_MsgStartup1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_startup_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgStartup, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_system_MsgStartup1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + + EXPECT_EQ(sbp_msg_startup_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgStartup1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_startup_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_startup_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgStartup, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.cause, greater.cause); + comparison_tests(lesser, greater); + } + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.reserved, greater.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_startup_t lesser = info.test_msg; + sbp_msg_startup_t greater = info.test_msg; + make_lesser_greater(lesser.startup_type, greater.startup_type); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgStartup); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_STARTUP"); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_startup_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_startup_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.startup, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.startup, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[4]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 4); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 4), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_startup_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 4); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgStartup, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStartup1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgStartup, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_system_MsgStatusJournal.cc b/c/test/cpp/auto_check_sbp_system_MsgStatusJournal.cc index 25e80933c6..781ef06af9 100644 --- a/c/test/cpp/auto_check_sbp_system_MsgStatusJournal.cc +++ b/c/test/cpp/auto_check_sbp_system_MsgStatusJournal.cc @@ -16,279 +16,1360 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_system_MsgStatusJournal0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_system_MsgStatusJournal0 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgStatusJournal0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgStatusJournal0() { + assign(test_msg_.journal[0].report.component, 6); + assign(test_msg_.journal[0].report.generic, 1); + assign(test_msg_.journal[0].report.specific, 13); + assign(test_msg_.journal[0].uptime, 4242); + + assign(test_msg_.journal[1].report.component, 6); + assign(test_msg_.journal[1].report.generic, 1); + assign(test_msg_.journal[1].report.specific, 14); + assign(test_msg_.journal[1].uptime, 5050); + + assign(test_msg_.journal[2].report.component, 6); + assign(test_msg_.journal[2].report.generic, 1); + assign(test_msg_.journal[2].report.specific, 15); + assign(test_msg_.journal[2].uptime, 8888); + assign(test_msg_.n_journal, 3); + assign(test_msg_.reporting_system, 1); + assign(test_msg_.sbp_version, 1025); + assign(test_msg_.sequence_descriptor, 16); + assign(test_msg_.total_status_reports, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_status_journal_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_status_journal_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgStatusJournal, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_status_journal_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgStatusJournal); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->status_journal, + sizeof(msg->status_journal)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_status_journal_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.status_journal, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgStatusJournal); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x7771; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 33; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_status_journal_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_status_journal_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_status_journal_t &lesser, + const sbp_msg_status_journal_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_status_journal_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_status_journal_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_status_journal_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_status_journal_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgStatusJournal, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); -TEST_F(Test_auto_check_sbp_system_MsgStatusJournal0, Test) { - uint8_t encoded_frame[] = { + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_status_journal_t test_msg_{}; + uint8_t encoded_frame_[33 + 8] = { 85, 253, 255, 211, 136, 33, 1, 0, 1, 4, 100, 0, 0, 0, 16, 146, 16, 0, 0, 6, 0, 1, 13, 186, 19, 0, 0, 6, 0, 1, 14, 184, 34, 0, 0, 6, 0, 1, 15, 113, 119, }; + uint8_t encoded_payload_[33] = { + 1, 0, 1, 4, 100, 0, 0, 0, 16, 146, 16, 0, 0, 6, 0, 1, 13, + 186, 19, 0, 0, 6, 0, 1, 14, 184, 34, 0, 0, 6, 0, 1, 15, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_status_journal_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgStatusJournal, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_status_journal_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgStatusJournal, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + + EXPECT_EQ(sbp_msg_status_journal_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + + for (uint8_t i = 0; i < 33; i++) { + EXPECT_EQ( + sbp_msg_status_journal_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgStatusJournal, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_status_journal_t t{}; + return sbp_msg_status_journal_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_status_journal_t t{}; + t.n_journal = 1; + return sbp_msg_status_journal_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_status_journal_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgStatusJournal, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.component, + greater.journal[0].report.component); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.generic, + greater.journal[0].report.generic); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.specific, + greater.journal[0].report.specific); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].uptime, greater.journal[0].uptime); + comparison_tests(lesser, greater); + } + + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[1].report.component, + greater.journal[1].report.component); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[1].report.generic, + greater.journal[1].report.generic); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[1].report.specific, + greater.journal[1].report.specific); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[1].uptime, greater.journal[1].uptime); + comparison_tests(lesser, greater); + } + + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[2].report.component, + greater.journal[2].report.component); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[2].report.generic, + greater.journal[2].report.generic); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[2].report.specific, + greater.journal[2].report.specific); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[2].uptime, greater.journal[2].uptime); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.n_journal, greater.n_journal); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.reporting_system, greater.reporting_system); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.sbp_version, greater.sbp_version); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.sequence_descriptor, + greater.sequence_descriptor); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.total_status_reports, + greater.total_status_reports); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgStatusJournal); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_STATUS_JOURNAL"); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_status_journal_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_status_journal_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.status_journal, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.status_journal, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[33]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 33); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 33), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 33); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgStatusJournal, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - sbp_msg_status_journal_t test_msg{}; - - test_msg.journal[0].report.component = 6; - test_msg.journal[0].report.generic = 1; - test_msg.journal[0].report.specific = 13; - test_msg.journal[0].uptime = 4242; - - test_msg.journal[1].report.component = 6; - test_msg.journal[1].report.generic = 1; - test_msg.journal[1].report.specific = 14; - test_msg.journal[1].uptime = 5050; - - test_msg.journal[2].report.component = 6; - test_msg.journal[2].report.generic = 1; - test_msg.journal[2].report.specific = 15; - test_msg.journal[2].uptime = 8888; - test_msg.n_journal = 3; - test_msg.reporting_system = 1; - test_msg.sbp_version = 1025; - test_msg.sequence_descriptor = 16; - test_msg.total_status_reports = 100; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.journal[0].report.component, 6) - << "incorrect value for last_msg_.journal[0].report.component, expected " - "6, is " - << last_msg_.journal[0].report.component; - EXPECT_EQ(last_msg_.journal[0].report.generic, 1) - << "incorrect value for last_msg_.journal[0].report.generic, expected 1, " - "is " - << last_msg_.journal[0].report.generic; - EXPECT_EQ(last_msg_.journal[0].report.specific, 13) - << "incorrect value for last_msg_.journal[0].report.specific, expected " - "13, is " - << last_msg_.journal[0].report.specific; - EXPECT_EQ(last_msg_.journal[0].uptime, 4242) - << "incorrect value for last_msg_.journal[0].uptime, expected 4242, is " - << last_msg_.journal[0].uptime; - EXPECT_EQ(last_msg_.journal[1].report.component, 6) - << "incorrect value for last_msg_.journal[1].report.component, expected " - "6, is " - << last_msg_.journal[1].report.component; - EXPECT_EQ(last_msg_.journal[1].report.generic, 1) - << "incorrect value for last_msg_.journal[1].report.generic, expected 1, " - "is " - << last_msg_.journal[1].report.generic; - EXPECT_EQ(last_msg_.journal[1].report.specific, 14) - << "incorrect value for last_msg_.journal[1].report.specific, expected " - "14, is " - << last_msg_.journal[1].report.specific; - EXPECT_EQ(last_msg_.journal[1].uptime, 5050) - << "incorrect value for last_msg_.journal[1].uptime, expected 5050, is " - << last_msg_.journal[1].uptime; - EXPECT_EQ(last_msg_.journal[2].report.component, 6) - << "incorrect value for last_msg_.journal[2].report.component, expected " - "6, is " - << last_msg_.journal[2].report.component; - EXPECT_EQ(last_msg_.journal[2].report.generic, 1) - << "incorrect value for last_msg_.journal[2].report.generic, expected 1, " - "is " - << last_msg_.journal[2].report.generic; - EXPECT_EQ(last_msg_.journal[2].report.specific, 15) - << "incorrect value for last_msg_.journal[2].report.specific, expected " - "15, is " - << last_msg_.journal[2].report.specific; - EXPECT_EQ(last_msg_.journal[2].uptime, 8888) - << "incorrect value for last_msg_.journal[2].uptime, expected 8888, is " - << last_msg_.journal[2].uptime; - EXPECT_EQ(last_msg_.n_journal, 3) - << "incorrect value for last_msg_.n_journal, expected 3, is " - << last_msg_.n_journal; - EXPECT_EQ(last_msg_.reporting_system, 1) - << "incorrect value for last_msg_.reporting_system, expected 1, is " - << last_msg_.reporting_system; - EXPECT_EQ(last_msg_.sbp_version, 1025) - << "incorrect value for last_msg_.sbp_version, expected 1025, is " - << last_msg_.sbp_version; - EXPECT_EQ(last_msg_.sequence_descriptor, 16) - << "incorrect value for last_msg_.sequence_descriptor, expected 16, is " - << last_msg_.sequence_descriptor; - EXPECT_EQ(last_msg_.total_status_reports, 100) - << "incorrect value for last_msg_.total_status_reports, expected 100, is " - << last_msg_.total_status_reports; -} -class Test_auto_check_sbp_system_MsgStatusJournal1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgStatusJournal, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_system_MsgStatusJournal1 : public ::testing::Test { public: - Test_auto_check_sbp_system_MsgStatusJournal1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_system_MsgStatusJournal1() { + assign(test_msg_.journal[0].report.component, 6); + assign(test_msg_.journal[0].report.generic, 1); + assign(test_msg_.journal[0].report.specific, 13); + assign(test_msg_.journal[0].uptime, 4242); + assign(test_msg_.n_journal, 1); + assign(test_msg_.reporting_system, 1); + assign(test_msg_.sbp_version, 1025); + assign(test_msg_.sequence_descriptor, 16); + assign(test_msg_.total_status_reports, 100); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_status_journal_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_status_journal_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgStatusJournal, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_status_journal_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgStatusJournal); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->status_journal, + sizeof(msg->status_journal)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_status_journal_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.status_journal, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgStatusJournal); + info.sender_id = 35027; + info.preamble = 0x55; + info.crc = 0x7990; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 17; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_status_journal_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_status_journal_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_status_journal_t &lesser, + const sbp_msg_status_journal_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_status_journal_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_status_journal_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_status_journal_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_status_journal_cmp(&greater, &lesser), 0); + + EXPECT_EQ( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgStatusJournal, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgStatusJournal, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_system_MsgStatusJournal1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_status_journal_t test_msg_{}; + uint8_t encoded_frame_[17 + 8] = { 85, 253, 255, 211, 136, 17, 1, 0, 1, 4, 100, 0, 0, 0, 16, 146, 16, 0, 0, 6, 0, 1, 13, 144, 121, }; + uint8_t encoded_payload_[17] = { + 1, 0, 1, 4, 100, 0, 0, 0, 16, 146, 16, 0, 0, 6, 0, 1, 13, + }; +}; + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_status_journal_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgStatusJournal, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_status_journal_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgStatusJournal, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + EXPECT_EQ(sbp_msg_status_journal_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + + for (uint8_t i = 0; i < 17; i++) { + EXPECT_EQ( + sbp_msg_status_journal_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgStatusJournal, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_status_journal_t t{}; + return sbp_msg_status_journal_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_status_journal_t t{}; + t.n_journal = 1; + return sbp_msg_status_journal_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_status_journal_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - sbp_msg_status_journal_t test_msg{}; - - test_msg.journal[0].report.component = 6; - test_msg.journal[0].report.generic = 1; - test_msg.journal[0].report.specific = 13; - test_msg.journal[0].uptime = 4242; - test_msg.n_journal = 1; - test_msg.reporting_system = 1; - test_msg.sbp_version = 1025; - test_msg.sequence_descriptor = 16; - test_msg.total_status_reports = 100; - - EXPECT_EQ(send_message(35027, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 35027); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.journal[0].report.component, 6) - << "incorrect value for last_msg_.journal[0].report.component, expected " - "6, is " - << last_msg_.journal[0].report.component; - EXPECT_EQ(last_msg_.journal[0].report.generic, 1) - << "incorrect value for last_msg_.journal[0].report.generic, expected 1, " - "is " - << last_msg_.journal[0].report.generic; - EXPECT_EQ(last_msg_.journal[0].report.specific, 13) - << "incorrect value for last_msg_.journal[0].report.specific, expected " - "13, is " - << last_msg_.journal[0].report.specific; - EXPECT_EQ(last_msg_.journal[0].uptime, 4242) - << "incorrect value for last_msg_.journal[0].uptime, expected 4242, is " - << last_msg_.journal[0].uptime; - EXPECT_EQ(last_msg_.n_journal, 1) - << "incorrect value for last_msg_.n_journal, expected 1, is " - << last_msg_.n_journal; - EXPECT_EQ(last_msg_.reporting_system, 1) - << "incorrect value for last_msg_.reporting_system, expected 1, is " - << last_msg_.reporting_system; - EXPECT_EQ(last_msg_.sbp_version, 1025) - << "incorrect value for last_msg_.sbp_version, expected 1025, is " - << last_msg_.sbp_version; - EXPECT_EQ(last_msg_.sequence_descriptor, 16) - << "incorrect value for last_msg_.sequence_descriptor, expected 16, is " - << last_msg_.sequence_descriptor; - EXPECT_EQ(last_msg_.total_status_reports, 100) - << "incorrect value for last_msg_.total_status_reports, expected 100, is " - << last_msg_.total_status_reports; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_status_journal_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); } + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgStatusJournal, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, Comparison) { + auto info = get_test_msg_info(); + + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.component, + greater.journal[0].report.component); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.generic, + greater.journal[0].report.generic); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].report.specific, + greater.journal[0].report.specific); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.journal[0].uptime, greater.journal[0].uptime); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.n_journal, greater.n_journal); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.reporting_system, greater.reporting_system); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.sbp_version, greater.sbp_version); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.sequence_descriptor, + greater.sequence_descriptor); + comparison_tests(lesser, greater); + } + { + sbp_msg_status_journal_t lesser = info.test_msg; + sbp_msg_status_journal_t greater = info.test_msg; + make_lesser_greater(lesser.total_status_reports, + greater.total_status_reports); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgStatusJournal); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_STATUS_JOURNAL"); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_status_journal_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_status_journal_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.status_journal, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.status_journal, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[17]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 17); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 17), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_status_journal_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 17); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgStatusJournal, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_system_MsgStatusJournal1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgStatusJournal, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_telemetry_MsgTelSv.cc b/c/test/cpp/auto_check_sbp_telemetry_MsgTelSv.cc index 3b29ba025b..b5442cfb6c 100644 --- a/c/test/cpp/auto_check_sbp_telemetry_MsgTelSv.cc +++ b/c/test/cpp/auto_check_sbp_telemetry_MsgTelSv.cc @@ -16,148 +16,678 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_telemetry_MsgTelSv0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_telemetry_MsgTelSv0 : public ::testing::Test { public: - Test_auto_check_sbp_telemetry_MsgTelSv0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_telemetry_MsgTelSv0() { + assign(test_msg_.n_obs, 16); + assign(test_msg_.n_sv_tel, 1); + assign(test_msg_.origin_flags, 1); + + assign(test_msg_.sv_tel[0].availability_flags, 5); + assign(test_msg_.sv_tel[0].az, 40); + assign(test_msg_.sv_tel[0].correction_flags, 1); + assign(test_msg_.sv_tel[0].el, 50); + assign(test_msg_.sv_tel[0].ephemeris_flags, 1); + assign(test_msg_.sv_tel[0].outlier_flags, 1); + assign(test_msg_.sv_tel[0].phase_residual, 1); + assign(test_msg_.sv_tel[0].pseudorange_residual, -30); + assign(test_msg_.sv_tel[0].sid.code, 12); + assign(test_msg_.sv_tel[0].sid.sat, 33); + assign(test_msg_.tow, 406773200); + assign(test_msg_.wn, 2223); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tel_sv_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tel_sv_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTelSv, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tel_sv_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTelSv); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tel_sv, sizeof(msg->tel_sv)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tel_sv_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tel_sv, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTelSv); + info.sender_id = 9876; + info.preamble = 0x55; + info.crc = 0x6927; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 20; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tel_sv_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tel_sv_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tel_sv_t &lesser, + const sbp_msg_tel_sv_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tel_sv_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tel_sv_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tel_sv_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tel_sv_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTelSv, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTelSv, &wrapped_greater, &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTelSv, &wrapped_lesser, &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTelSv, &wrapped_greater, &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_telemetry_MsgTelSv0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tel_sv_t test_msg_{}; + uint8_t encoded_frame_[20 + 8] = { 85, 32, 1, 148, 38, 20, 175, 8, 208, 221, 62, 24, 16, 1, 40, 50, 5, 226, 255, 1, 0, 1, 1, 1, 33, 12, 39, 105, }; + uint8_t encoded_payload_[20] = { + 175, 8, 208, 221, 62, 24, 16, 1, 40, 50, + 5, 226, 255, 1, 0, 1, 1, 1, 33, 12, + }; +}; + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tel_sv_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTelSv, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_tel_sv_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgTelSv, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + EXPECT_EQ( + sbp_msg_tel_sv_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); +} +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + + for (uint8_t i = 0; i < 20; i++) { + EXPECT_EQ(sbp_msg_tel_sv_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tel_sv_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tel_sv_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTelSv, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tel_sv_t msg{}; + + EXPECT_EQ(sbp_msg_tel_sv_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tel_sv_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tel_sv_t t{}; + return sbp_msg_tel_sv_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tel_sv_t t{}; + t.n_sv_tel = 1; + return sbp_msg_tel_sv_encoded_len(&t); + }() - overhead; - sbp_msg_tel_sv_t test_msg{}; - test_msg.n_obs = 16; - test_msg.n_sv_tel = 1; - test_msg.origin_flags = 1; - - test_msg.sv_tel[0].availability_flags = 5; - test_msg.sv_tel[0].az = 40; - test_msg.sv_tel[0].correction_flags = 1; - test_msg.sv_tel[0].el = 50; - test_msg.sv_tel[0].ephemeris_flags = 1; - test_msg.sv_tel[0].outlier_flags = 1; - test_msg.sv_tel[0].phase_residual = 1; - test_msg.sv_tel[0].pseudorange_residual = -30; - test_msg.sv_tel[0].sid.code = 12; - test_msg.sv_tel[0].sid.sat = 33; - test_msg.tow = 406773200; - test_msg.wn = 2223; - - EXPECT_EQ(send_message(9876, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 9876); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_obs, 16) - << "incorrect value for last_msg_.n_obs, expected 16, is " - << last_msg_.n_obs; - EXPECT_EQ(last_msg_.n_sv_tel, 1) - << "incorrect value for last_msg_.n_sv_tel, expected 1, is " - << last_msg_.n_sv_tel; - EXPECT_EQ(last_msg_.origin_flags, 1) - << "incorrect value for last_msg_.origin_flags, expected 1, is " - << last_msg_.origin_flags; - EXPECT_EQ(last_msg_.sv_tel[0].availability_flags, 5) - << "incorrect value for last_msg_.sv_tel[0].availability_flags, expected " - "5, is " - << last_msg_.sv_tel[0].availability_flags; - EXPECT_EQ(last_msg_.sv_tel[0].az, 40) - << "incorrect value for last_msg_.sv_tel[0].az, expected 40, is " - << last_msg_.sv_tel[0].az; - EXPECT_EQ(last_msg_.sv_tel[0].correction_flags, 1) - << "incorrect value for last_msg_.sv_tel[0].correction_flags, expected " - "1, is " - << last_msg_.sv_tel[0].correction_flags; - EXPECT_EQ(last_msg_.sv_tel[0].el, 50) - << "incorrect value for last_msg_.sv_tel[0].el, expected 50, is " - << last_msg_.sv_tel[0].el; - EXPECT_EQ(last_msg_.sv_tel[0].ephemeris_flags, 1) - << "incorrect value for last_msg_.sv_tel[0].ephemeris_flags, expected 1, " - "is " - << last_msg_.sv_tel[0].ephemeris_flags; - EXPECT_EQ(last_msg_.sv_tel[0].outlier_flags, 1) - << "incorrect value for last_msg_.sv_tel[0].outlier_flags, expected 1, " - "is " - << last_msg_.sv_tel[0].outlier_flags; - EXPECT_EQ(last_msg_.sv_tel[0].phase_residual, 1) - << "incorrect value for last_msg_.sv_tel[0].phase_residual, expected 1, " - "is " - << last_msg_.sv_tel[0].phase_residual; - EXPECT_EQ(last_msg_.sv_tel[0].pseudorange_residual, -30) - << "incorrect value for last_msg_.sv_tel[0].pseudorange_residual, " - "expected -30, is " - << last_msg_.sv_tel[0].pseudorange_residual; - EXPECT_EQ(last_msg_.sv_tel[0].sid.code, 12) - << "incorrect value for last_msg_.sv_tel[0].sid.code, expected 12, is " - << last_msg_.sv_tel[0].sid.code; - EXPECT_EQ(last_msg_.sv_tel[0].sid.sat, 33) - << "incorrect value for last_msg_.sv_tel[0].sid.sat, expected 33, is " - << last_msg_.sv_tel[0].sid.sat; - EXPECT_EQ(last_msg_.tow, 406773200) - << "incorrect value for last_msg_.tow, expected 406773200, is " - << last_msg_.tow; - EXPECT_EQ(last_msg_.wn, 2223) - << "incorrect value for last_msg_.wn, expected 2223, is " << last_msg_.wn; + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tel_sv_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tel_sv_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTelSv, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.n_obs, greater.n_obs); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.n_sv_tel, greater.n_sv_tel); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.origin_flags, greater.origin_flags); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].availability_flags, + greater.sv_tel[0].availability_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].az, greater.sv_tel[0].az); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].correction_flags, + greater.sv_tel[0].correction_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].el, greater.sv_tel[0].el); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].ephemeris_flags, + greater.sv_tel[0].ephemeris_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].outlier_flags, + greater.sv_tel[0].outlier_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].phase_residual, + greater.sv_tel[0].phase_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].pseudorange_residual, + greater.sv_tel[0].pseudorange_residual); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].sid.code, greater.sv_tel[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.sv_tel[0].sid.sat, greater.sv_tel[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tel_sv_t lesser = info.test_msg; + sbp_msg_tel_sv_t greater = info.test_msg; + make_lesser_greater(lesser.wn, greater.wn); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgTelSv); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_TEL_SV"); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tel_sv_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tel_sv_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.tel_sv, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.tel_sv, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[20]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 20); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 20), 0); } + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tel_sv_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 20); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTelSv, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_telemetry_MsgTelSv0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgTelSv, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_tracking_MsgMeasurementState.cc b/c/test/cpp/auto_check_sbp_tracking_MsgMeasurementState.cc index 397c9213cf..f6beae657f 100644 --- a/c/test/cpp/auto_check_sbp_tracking_MsgMeasurementState.cc +++ b/c/test/cpp/auto_check_sbp_tracking_MsgMeasurementState.cc @@ -16,66 +16,594 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_tracking_MsgMeasurementState0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_tracking_MsgMeasurementState0 + : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgMeasurementState0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgMeasurementState0() { + assign(test_msg_.n_states, 79); + + assign(test_msg_.states[0].cn0, 162); + assign(test_msg_.states[0].mesid.code, 0); + assign(test_msg_.states[0].mesid.sat, 29); + + assign(test_msg_.states[1].cn0, 0); + assign(test_msg_.states[1].mesid.code, 0); + assign(test_msg_.states[1].mesid.sat, 0); + + assign(test_msg_.states[2].cn0, 0); + assign(test_msg_.states[2].mesid.code, 0); + assign(test_msg_.states[2].mesid.sat, 0); + + assign(test_msg_.states[3].cn0, 201); + assign(test_msg_.states[3].mesid.code, 0); + assign(test_msg_.states[3].mesid.sat, 27); + + assign(test_msg_.states[4].cn0, 168); + assign(test_msg_.states[4].mesid.code, 0); + assign(test_msg_.states[4].mesid.sat, 20); + + assign(test_msg_.states[5].cn0, 184); + assign(test_msg_.states[5].mesid.code, 0); + assign(test_msg_.states[5].mesid.sat, 32); + + assign(test_msg_.states[6].cn0, 187); + assign(test_msg_.states[6].mesid.code, 0); + assign(test_msg_.states[6].mesid.sat, 15); + + assign(test_msg_.states[7].cn0, 0); + assign(test_msg_.states[7].mesid.code, 0); + assign(test_msg_.states[7].mesid.sat, 0); + + assign(test_msg_.states[8].cn0, 210); + assign(test_msg_.states[8].mesid.code, 0); + assign(test_msg_.states[8].mesid.sat, 18); + + assign(test_msg_.states[9].cn0, 167); + assign(test_msg_.states[9].mesid.code, 0); + assign(test_msg_.states[9].mesid.sat, 16); + + assign(test_msg_.states[10].cn0, 0); + assign(test_msg_.states[10].mesid.code, 0); + assign(test_msg_.states[10].mesid.sat, 0); + + assign(test_msg_.states[11].cn0, 213); + assign(test_msg_.states[11].mesid.code, 0); + assign(test_msg_.states[11].mesid.sat, 23); + + assign(test_msg_.states[12].cn0, 223); + assign(test_msg_.states[12].mesid.code, 0); + assign(test_msg_.states[12].mesid.sat, 10); + + assign(test_msg_.states[13].cn0, 0); + assign(test_msg_.states[13].mesid.code, 0); + assign(test_msg_.states[13].mesid.sat, 0); + + assign(test_msg_.states[14].cn0, 0); + assign(test_msg_.states[14].mesid.code, 0); + assign(test_msg_.states[14].mesid.sat, 0); + + assign(test_msg_.states[15].cn0, 0); + assign(test_msg_.states[15].mesid.code, 0); + assign(test_msg_.states[15].mesid.sat, 0); + + assign(test_msg_.states[16].cn0, 0); + assign(test_msg_.states[16].mesid.code, 0); + assign(test_msg_.states[16].mesid.sat, 0); + + assign(test_msg_.states[17].cn0, 202); + assign(test_msg_.states[17].mesid.code, 2); + assign(test_msg_.states[17].mesid.sat, 131); + + assign(test_msg_.states[18].cn0, 192); + assign(test_msg_.states[18].mesid.code, 1); + assign(test_msg_.states[18].mesid.sat, 27); + + assign(test_msg_.states[19].cn0, 165); + assign(test_msg_.states[19].mesid.code, 1); + assign(test_msg_.states[19].mesid.sat, 15); + + assign(test_msg_.states[20].cn0, 146); + assign(test_msg_.states[20].mesid.code, 1); + assign(test_msg_.states[20].mesid.sat, 29); + + assign(test_msg_.states[21].cn0, 170); + assign(test_msg_.states[21].mesid.code, 1); + assign(test_msg_.states[21].mesid.sat, 32); + + assign(test_msg_.states[22].cn0, 201); + assign(test_msg_.states[22].mesid.code, 1); + assign(test_msg_.states[22].mesid.sat, 18); + + assign(test_msg_.states[23].cn0, 0); + assign(test_msg_.states[23].mesid.code, 0); + assign(test_msg_.states[23].mesid.sat, 0); + + assign(test_msg_.states[24].cn0, 0); + assign(test_msg_.states[24].mesid.code, 0); + assign(test_msg_.states[24].mesid.sat, 0); + + assign(test_msg_.states[25].cn0, 0); + assign(test_msg_.states[25].mesid.code, 0); + assign(test_msg_.states[25].mesid.sat, 0); + + assign(test_msg_.states[26].cn0, 212); + assign(test_msg_.states[26].mesid.code, 1); + assign(test_msg_.states[26].mesid.sat, 23); + + assign(test_msg_.states[27].cn0, 205); + assign(test_msg_.states[27].mesid.code, 1); + assign(test_msg_.states[27].mesid.sat, 10); + + assign(test_msg_.states[28].cn0, 0); + assign(test_msg_.states[28].mesid.code, 0); + assign(test_msg_.states[28].mesid.sat, 0); + + assign(test_msg_.states[29].cn0, 230); + assign(test_msg_.states[29].mesid.code, 3); + assign(test_msg_.states[29].mesid.sat, 96); + + assign(test_msg_.states[30].cn0, 0); + assign(test_msg_.states[30].mesid.code, 0); + assign(test_msg_.states[30].mesid.sat, 0); + + assign(test_msg_.states[31].cn0, 214); + assign(test_msg_.states[31].mesid.code, 3); + assign(test_msg_.states[31].mesid.sat, 101); + + assign(test_msg_.states[32].cn0, 212); + assign(test_msg_.states[32].mesid.code, 3); + assign(test_msg_.states[32].mesid.sat, 103); + + assign(test_msg_.states[33].cn0, 209); + assign(test_msg_.states[33].mesid.code, 3); + assign(test_msg_.states[33].mesid.sat, 104); + + assign(test_msg_.states[34].cn0, 157); + assign(test_msg_.states[34].mesid.code, 3); + assign(test_msg_.states[34].mesid.sat, 106); + + assign(test_msg_.states[35].cn0, 230); + assign(test_msg_.states[35].mesid.code, 3); + assign(test_msg_.states[35].mesid.sat, 102); + + assign(test_msg_.states[36].cn0, 0); + assign(test_msg_.states[36].mesid.code, 0); + assign(test_msg_.states[36].mesid.sat, 0); + + assign(test_msg_.states[37].cn0, 0); + assign(test_msg_.states[37].mesid.code, 0); + assign(test_msg_.states[37].mesid.sat, 0); + + assign(test_msg_.states[38].cn0, 189); + assign(test_msg_.states[38].mesid.code, 4); + assign(test_msg_.states[38].mesid.sat, 101); + + assign(test_msg_.states[39].cn0, 207); + assign(test_msg_.states[39].mesid.code, 4); + assign(test_msg_.states[39].mesid.sat, 96); + + assign(test_msg_.states[40].cn0, 164); + assign(test_msg_.states[40].mesid.code, 4); + assign(test_msg_.states[40].mesid.sat, 106); + + assign(test_msg_.states[41].cn0, 193); + assign(test_msg_.states[41].mesid.code, 4); + assign(test_msg_.states[41].mesid.sat, 104); + + assign(test_msg_.states[42].cn0, 0); + assign(test_msg_.states[42].mesid.code, 0); + assign(test_msg_.states[42].mesid.sat, 0); + + assign(test_msg_.states[43].cn0, 208); + assign(test_msg_.states[43].mesid.code, 4); + assign(test_msg_.states[43].mesid.sat, 102); + + assign(test_msg_.states[44].cn0, 0); + assign(test_msg_.states[44].mesid.code, 0); + assign(test_msg_.states[44].mesid.sat, 0); + + assign(test_msg_.states[45].cn0, 212); + assign(test_msg_.states[45].mesid.code, 12); + assign(test_msg_.states[45].mesid.sat, 27); + + assign(test_msg_.states[46].cn0, 161); + assign(test_msg_.states[46].mesid.code, 12); + assign(test_msg_.states[46].mesid.sat, 29); + + assign(test_msg_.states[47].cn0, 216); + assign(test_msg_.states[47].mesid.code, 12); + assign(test_msg_.states[47].mesid.sat, 32); + + assign(test_msg_.states[48].cn0, 216); + assign(test_msg_.states[48].mesid.code, 12); + assign(test_msg_.states[48].mesid.sat, 30); + + assign(test_msg_.states[49].cn0, 178); + assign(test_msg_.states[49].mesid.code, 12); + assign(test_msg_.states[49].mesid.sat, 20); + + assign(test_msg_.states[50].cn0, 0); + assign(test_msg_.states[50].mesid.code, 0); + assign(test_msg_.states[50].mesid.sat, 0); + + assign(test_msg_.states[51].cn0, 0); + assign(test_msg_.states[51].mesid.code, 0); + assign(test_msg_.states[51].mesid.sat, 0); + + assign(test_msg_.states[52].cn0, 0); + assign(test_msg_.states[52].mesid.code, 0); + assign(test_msg_.states[52].mesid.sat, 0); + + assign(test_msg_.states[53].cn0, 0); + assign(test_msg_.states[53].mesid.code, 0); + assign(test_msg_.states[53].mesid.sat, 0); + + assign(test_msg_.states[54].cn0, 0); + assign(test_msg_.states[54].mesid.code, 0); + assign(test_msg_.states[54].mesid.sat, 0); + + assign(test_msg_.states[55].cn0, 0); + assign(test_msg_.states[55].mesid.code, 0); + assign(test_msg_.states[55].mesid.sat, 0); + + assign(test_msg_.states[56].cn0, 0); + assign(test_msg_.states[56].mesid.code, 0); + assign(test_msg_.states[56].mesid.sat, 0); + + assign(test_msg_.states[57].cn0, 0); + assign(test_msg_.states[57].mesid.code, 0); + assign(test_msg_.states[57].mesid.sat, 0); + + assign(test_msg_.states[58].cn0, 0); + assign(test_msg_.states[58].mesid.code, 0); + assign(test_msg_.states[58].mesid.sat, 0); + + assign(test_msg_.states[59].cn0, 0); + assign(test_msg_.states[59].mesid.code, 0); + assign(test_msg_.states[59].mesid.sat, 0); + + assign(test_msg_.states[60].cn0, 0); + assign(test_msg_.states[60].mesid.code, 0); + assign(test_msg_.states[60].mesid.sat, 0); + + assign(test_msg_.states[61].cn0, 0); + assign(test_msg_.states[61].mesid.code, 0); + assign(test_msg_.states[61].mesid.sat, 0); + + assign(test_msg_.states[62].cn0, 0); + assign(test_msg_.states[62].mesid.code, 0); + assign(test_msg_.states[62].mesid.sat, 0); + + assign(test_msg_.states[63].cn0, 203); + assign(test_msg_.states[63].mesid.code, 14); + assign(test_msg_.states[63].mesid.sat, 36); + + assign(test_msg_.states[64].cn0, 0); + assign(test_msg_.states[64].mesid.code, 0); + assign(test_msg_.states[64].mesid.sat, 0); + + assign(test_msg_.states[65].cn0, 158); + assign(test_msg_.states[65].mesid.code, 14); + assign(test_msg_.states[65].mesid.sat, 5); + + assign(test_msg_.states[66].cn0, 194); + assign(test_msg_.states[66].mesid.code, 14); + assign(test_msg_.states[66].mesid.sat, 4); + + assign(test_msg_.states[67].cn0, 192); + assign(test_msg_.states[67].mesid.code, 14); + assign(test_msg_.states[67].mesid.sat, 11); + + assign(test_msg_.states[68].cn0, 207); + assign(test_msg_.states[68].mesid.code, 14); + assign(test_msg_.states[68].mesid.sat, 9); + + assign(test_msg_.states[69].cn0, 0); + assign(test_msg_.states[69].mesid.code, 0); + assign(test_msg_.states[69].mesid.sat, 0); + + assign(test_msg_.states[70].cn0, 0); + assign(test_msg_.states[70].mesid.code, 0); + assign(test_msg_.states[70].mesid.sat, 0); + + assign(test_msg_.states[71].cn0, 0); + assign(test_msg_.states[71].mesid.code, 0); + assign(test_msg_.states[71].mesid.sat, 0); + + assign(test_msg_.states[72].cn0, 218); + assign(test_msg_.states[72].mesid.code, 20); + assign(test_msg_.states[72].mesid.sat, 9); + + assign(test_msg_.states[73].cn0, 176); + assign(test_msg_.states[73].mesid.code, 20); + assign(test_msg_.states[73].mesid.sat, 5); + + assign(test_msg_.states[74].cn0, 217); + assign(test_msg_.states[74].mesid.code, 20); + assign(test_msg_.states[74].mesid.sat, 36); + + assign(test_msg_.states[75].cn0, 200); + assign(test_msg_.states[75].mesid.code, 20); + assign(test_msg_.states[75].mesid.sat, 11); + + assign(test_msg_.states[76].cn0, 205); + assign(test_msg_.states[76].mesid.code, 20); + assign(test_msg_.states[76].mesid.sat, 4); + + assign(test_msg_.states[77].cn0, 0); + assign(test_msg_.states[77].mesid.code, 0); + assign(test_msg_.states[77].mesid.sat, 0); + + assign(test_msg_.states[78].cn0, 0); + assign(test_msg_.states[78].mesid.code, 0); + assign(test_msg_.states[78].mesid.sat, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_measurement_state_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_measurement_state_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgMeasurementState, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_measurement_state_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgMeasurementState); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->measurement_state, + sizeof(msg->measurement_state)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_measurement_state_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.measurement_state, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgMeasurementState); + info.sender_id = 31183; + info.preamble = 0x55; + info.crc = 0x3623; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 237; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_measurement_state_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_measurement_state_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_measurement_state_t &lesser, + const sbp_msg_measurement_state_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_measurement_state_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_measurement_state_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_measurement_state_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_measurement_state_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgMeasurementState, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgMeasurementState, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgMeasurementState, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgMeasurementState, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_tracking_MsgMeasurementState0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_measurement_state_t test_msg_{}; + uint8_t encoded_frame_[237 + 8] = { 85, 97, 0, 207, 121, 237, 29, 0, 162, 0, 0, 0, 0, 0, 0, 27, 0, 201, 20, 0, 168, 32, 0, 184, 15, 0, 187, 0, 0, 0, 18, 0, 210, 16, 0, 167, 0, 0, 0, 23, 0, 213, 10, 0, 223, @@ -94,1050 +622,1996 @@ TEST_F(Test_auto_check_sbp_tracking_MsgMeasurementState0, Test) { 5, 20, 176, 36, 20, 217, 11, 20, 200, 4, 20, 205, 0, 0, 0, 0, 0, 0, 35, 54, }; + uint8_t encoded_payload_[237] = { + 29, 0, 162, 0, 0, 0, 0, 0, 0, 27, 0, 201, 20, 0, 168, + 32, 0, 184, 15, 0, 187, 0, 0, 0, 18, 0, 210, 16, 0, 167, + 0, 0, 0, 23, 0, 213, 10, 0, 223, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 131, 2, 202, 27, 1, 192, 15, 1, 165, + 29, 1, 146, 32, 1, 170, 18, 1, 201, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 23, 1, 212, 10, 1, 205, 0, 0, 0, 96, 3, 230, + 0, 0, 0, 101, 3, 214, 103, 3, 212, 104, 3, 209, 106, 3, 157, + 102, 3, 230, 0, 0, 0, 0, 0, 0, 101, 4, 189, 96, 4, 207, + 106, 4, 164, 104, 4, 193, 0, 0, 0, 102, 4, 208, 0, 0, 0, + 27, 12, 212, 29, 12, 161, 32, 12, 216, 30, 12, 216, 20, 12, 178, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 14, 203, 0, 0, 0, + 5, 14, 158, 4, 14, 194, 11, 14, 192, 9, 14, 207, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 9, 20, 218, 5, 20, 176, 36, 20, 217, + 11, 20, 200, 4, 20, 205, 0, 0, 0, 0, 0, 0, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_measurement_state_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgMeasurementState, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[237]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_measurement_state_encode(&buf[0], sizeof(buf), &n_written, + &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 237); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 237), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgMeasurementState, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 237); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 237), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[237]; + + EXPECT_EQ(sbp_msg_measurement_state_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 237), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[237]; + + for (uint8_t i = 0; i < 237; i++) { + EXPECT_EQ( + sbp_msg_measurement_state_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_measurement_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_measurement_state_decode(&info.encoded_payload[0], + info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 237); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgMeasurementState, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 237); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_measurement_state_t msg{}; + + EXPECT_EQ(sbp_msg_measurement_state_decode(&info.encoded_payload[0], + info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_measurement_state_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_measurement_state_t t{}; + return sbp_msg_measurement_state_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_measurement_state_t t{}; + t.n_states = 1; + return sbp_msg_measurement_state_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_measurement_state_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_measurement_state_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgMeasurementState, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].mesid.code, + greater.states[0].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].mesid.sat, + greater.states[0].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].mesid.code, + greater.states[1].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].mesid.sat, + greater.states[1].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].mesid.code, + greater.states[2].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].mesid.sat, + greater.states[2].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].mesid.code, + greater.states[3].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].mesid.sat, + greater.states[3].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].mesid.code, + greater.states[4].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].mesid.sat, + greater.states[4].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].mesid.code, + greater.states[5].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].mesid.sat, + greater.states[5].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].mesid.code, + greater.states[6].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].mesid.sat, + greater.states[6].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].mesid.code, + greater.states[7].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].mesid.sat, + greater.states[7].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].mesid.code, + greater.states[8].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].mesid.sat, + greater.states[8].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].mesid.code, + greater.states[9].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].mesid.sat, + greater.states[9].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].mesid.code, + greater.states[10].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].mesid.sat, + greater.states[10].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[11].cn0, greater.states[11].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[11].mesid.code, + greater.states[11].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[11].mesid.sat, + greater.states[11].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[12].cn0, greater.states[12].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[12].mesid.code, + greater.states[12].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[12].mesid.sat, + greater.states[12].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[13].cn0, greater.states[13].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[13].mesid.code, + greater.states[13].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[13].mesid.sat, + greater.states[13].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[14].cn0, greater.states[14].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[14].mesid.code, + greater.states[14].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[14].mesid.sat, + greater.states[14].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[15].cn0, greater.states[15].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[15].mesid.code, + greater.states[15].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[15].mesid.sat, + greater.states[15].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[16].cn0, greater.states[16].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[16].mesid.code, + greater.states[16].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[16].mesid.sat, + greater.states[16].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[17].cn0, greater.states[17].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[17].mesid.code, + greater.states[17].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[17].mesid.sat, + greater.states[17].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[18].cn0, greater.states[18].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[18].mesid.code, + greater.states[18].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[18].mesid.sat, + greater.states[18].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[19].cn0, greater.states[19].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[19].mesid.code, + greater.states[19].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[19].mesid.sat, + greater.states[19].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[20].cn0, greater.states[20].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[20].mesid.code, + greater.states[20].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[20].mesid.sat, + greater.states[20].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[21].cn0, greater.states[21].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[21].mesid.code, + greater.states[21].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[21].mesid.sat, + greater.states[21].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[22].cn0, greater.states[22].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[22].mesid.code, + greater.states[22].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[22].mesid.sat, + greater.states[22].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[23].cn0, greater.states[23].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[23].mesid.code, + greater.states[23].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[23].mesid.sat, + greater.states[23].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[24].cn0, greater.states[24].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[24].mesid.code, + greater.states[24].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[24].mesid.sat, + greater.states[24].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[25].cn0, greater.states[25].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[25].mesid.code, + greater.states[25].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[25].mesid.sat, + greater.states[25].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[26].cn0, greater.states[26].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[26].mesid.code, + greater.states[26].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[26].mesid.sat, + greater.states[26].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[27].cn0, greater.states[27].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[27].mesid.code, + greater.states[27].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[27].mesid.sat, + greater.states[27].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[28].cn0, greater.states[28].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[28].mesid.code, + greater.states[28].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[28].mesid.sat, + greater.states[28].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[29].cn0, greater.states[29].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[29].mesid.code, + greater.states[29].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[29].mesid.sat, + greater.states[29].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[30].cn0, greater.states[30].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[30].mesid.code, + greater.states[30].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[30].mesid.sat, + greater.states[30].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[31].cn0, greater.states[31].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[31].mesid.code, + greater.states[31].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[31].mesid.sat, + greater.states[31].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[32].cn0, greater.states[32].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[32].mesid.code, + greater.states[32].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[32].mesid.sat, + greater.states[32].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[33].cn0, greater.states[33].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[33].mesid.code, + greater.states[33].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[33].mesid.sat, + greater.states[33].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[34].cn0, greater.states[34].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[34].mesid.code, + greater.states[34].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[34].mesid.sat, + greater.states[34].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[35].cn0, greater.states[35].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[35].mesid.code, + greater.states[35].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[35].mesid.sat, + greater.states[35].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[36].cn0, greater.states[36].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[36].mesid.code, + greater.states[36].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[36].mesid.sat, + greater.states[36].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[37].cn0, greater.states[37].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[37].mesid.code, + greater.states[37].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[37].mesid.sat, + greater.states[37].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[38].cn0, greater.states[38].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[38].mesid.code, + greater.states[38].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[38].mesid.sat, + greater.states[38].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[39].cn0, greater.states[39].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[39].mesid.code, + greater.states[39].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[39].mesid.sat, + greater.states[39].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[40].cn0, greater.states[40].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[40].mesid.code, + greater.states[40].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[40].mesid.sat, + greater.states[40].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[41].cn0, greater.states[41].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[41].mesid.code, + greater.states[41].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[41].mesid.sat, + greater.states[41].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[42].cn0, greater.states[42].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[42].mesid.code, + greater.states[42].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[42].mesid.sat, + greater.states[42].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[43].cn0, greater.states[43].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[43].mesid.code, + greater.states[43].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[43].mesid.sat, + greater.states[43].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[44].cn0, greater.states[44].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[44].mesid.code, + greater.states[44].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[44].mesid.sat, + greater.states[44].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[45].cn0, greater.states[45].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[45].mesid.code, + greater.states[45].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[45].mesid.sat, + greater.states[45].mesid.sat); + comparison_tests(lesser, greater); + } + + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[46].cn0, greater.states[46].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[46].mesid.code, + greater.states[46].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[46].mesid.sat, + greater.states[46].mesid.sat); + comparison_tests(lesser, greater); + } - sbp_msg_measurement_state_t test_msg{}; - test_msg.n_states = 79; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[47].cn0, greater.states[47].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[47].mesid.code, + greater.states[47].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[47].mesid.sat, + greater.states[47].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[0].cn0 = 162; - test_msg.states[0].mesid.code = 0; - test_msg.states[0].mesid.sat = 29; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[48].cn0, greater.states[48].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[48].mesid.code, + greater.states[48].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[48].mesid.sat, + greater.states[48].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[1].cn0 = 0; - test_msg.states[1].mesid.code = 0; - test_msg.states[1].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[49].cn0, greater.states[49].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[49].mesid.code, + greater.states[49].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[49].mesid.sat, + greater.states[49].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[2].cn0 = 0; - test_msg.states[2].mesid.code = 0; - test_msg.states[2].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[50].cn0, greater.states[50].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[50].mesid.code, + greater.states[50].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[50].mesid.sat, + greater.states[50].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[3].cn0 = 201; - test_msg.states[3].mesid.code = 0; - test_msg.states[3].mesid.sat = 27; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[51].cn0, greater.states[51].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[51].mesid.code, + greater.states[51].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[51].mesid.sat, + greater.states[51].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[4].cn0 = 168; - test_msg.states[4].mesid.code = 0; - test_msg.states[4].mesid.sat = 20; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[52].cn0, greater.states[52].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[52].mesid.code, + greater.states[52].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[52].mesid.sat, + greater.states[52].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[5].cn0 = 184; - test_msg.states[5].mesid.code = 0; - test_msg.states[5].mesid.sat = 32; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[53].cn0, greater.states[53].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[53].mesid.code, + greater.states[53].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[53].mesid.sat, + greater.states[53].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[6].cn0 = 187; - test_msg.states[6].mesid.code = 0; - test_msg.states[6].mesid.sat = 15; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[54].cn0, greater.states[54].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[54].mesid.code, + greater.states[54].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[54].mesid.sat, + greater.states[54].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[7].cn0 = 0; - test_msg.states[7].mesid.code = 0; - test_msg.states[7].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[55].cn0, greater.states[55].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[55].mesid.code, + greater.states[55].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[55].mesid.sat, + greater.states[55].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[8].cn0 = 210; - test_msg.states[8].mesid.code = 0; - test_msg.states[8].mesid.sat = 18; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[56].cn0, greater.states[56].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[56].mesid.code, + greater.states[56].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[56].mesid.sat, + greater.states[56].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[9].cn0 = 167; - test_msg.states[9].mesid.code = 0; - test_msg.states[9].mesid.sat = 16; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[57].cn0, greater.states[57].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[57].mesid.code, + greater.states[57].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[57].mesid.sat, + greater.states[57].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[10].cn0 = 0; - test_msg.states[10].mesid.code = 0; - test_msg.states[10].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[58].cn0, greater.states[58].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[58].mesid.code, + greater.states[58].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[58].mesid.sat, + greater.states[58].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[11].cn0 = 213; - test_msg.states[11].mesid.code = 0; - test_msg.states[11].mesid.sat = 23; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[59].cn0, greater.states[59].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[59].mesid.code, + greater.states[59].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[59].mesid.sat, + greater.states[59].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[12].cn0 = 223; - test_msg.states[12].mesid.code = 0; - test_msg.states[12].mesid.sat = 10; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[60].cn0, greater.states[60].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[60].mesid.code, + greater.states[60].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[60].mesid.sat, + greater.states[60].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[13].cn0 = 0; - test_msg.states[13].mesid.code = 0; - test_msg.states[13].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[61].cn0, greater.states[61].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[61].mesid.code, + greater.states[61].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[61].mesid.sat, + greater.states[61].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[14].cn0 = 0; - test_msg.states[14].mesid.code = 0; - test_msg.states[14].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[62].cn0, greater.states[62].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[62].mesid.code, + greater.states[62].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[62].mesid.sat, + greater.states[62].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[15].cn0 = 0; - test_msg.states[15].mesid.code = 0; - test_msg.states[15].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[63].cn0, greater.states[63].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[63].mesid.code, + greater.states[63].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[63].mesid.sat, + greater.states[63].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[16].cn0 = 0; - test_msg.states[16].mesid.code = 0; - test_msg.states[16].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[64].cn0, greater.states[64].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[64].mesid.code, + greater.states[64].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[64].mesid.sat, + greater.states[64].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[17].cn0 = 202; - test_msg.states[17].mesid.code = 2; - test_msg.states[17].mesid.sat = 131; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[65].cn0, greater.states[65].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[65].mesid.code, + greater.states[65].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[65].mesid.sat, + greater.states[65].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[18].cn0 = 192; - test_msg.states[18].mesid.code = 1; - test_msg.states[18].mesid.sat = 27; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[66].cn0, greater.states[66].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[66].mesid.code, + greater.states[66].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[66].mesid.sat, + greater.states[66].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[19].cn0 = 165; - test_msg.states[19].mesid.code = 1; - test_msg.states[19].mesid.sat = 15; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[67].cn0, greater.states[67].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[67].mesid.code, + greater.states[67].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[67].mesid.sat, + greater.states[67].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[20].cn0 = 146; - test_msg.states[20].mesid.code = 1; - test_msg.states[20].mesid.sat = 29; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[68].cn0, greater.states[68].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[68].mesid.code, + greater.states[68].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[68].mesid.sat, + greater.states[68].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[21].cn0 = 170; - test_msg.states[21].mesid.code = 1; - test_msg.states[21].mesid.sat = 32; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[69].cn0, greater.states[69].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[69].mesid.code, + greater.states[69].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[69].mesid.sat, + greater.states[69].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[22].cn0 = 201; - test_msg.states[22].mesid.code = 1; - test_msg.states[22].mesid.sat = 18; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[70].cn0, greater.states[70].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[70].mesid.code, + greater.states[70].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[70].mesid.sat, + greater.states[70].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[23].cn0 = 0; - test_msg.states[23].mesid.code = 0; - test_msg.states[23].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[71].cn0, greater.states[71].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[71].mesid.code, + greater.states[71].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[71].mesid.sat, + greater.states[71].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[24].cn0 = 0; - test_msg.states[24].mesid.code = 0; - test_msg.states[24].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[72].cn0, greater.states[72].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[72].mesid.code, + greater.states[72].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[72].mesid.sat, + greater.states[72].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[25].cn0 = 0; - test_msg.states[25].mesid.code = 0; - test_msg.states[25].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[73].cn0, greater.states[73].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[73].mesid.code, + greater.states[73].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[73].mesid.sat, + greater.states[73].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[26].cn0 = 212; - test_msg.states[26].mesid.code = 1; - test_msg.states[26].mesid.sat = 23; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[74].cn0, greater.states[74].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[74].mesid.code, + greater.states[74].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[74].mesid.sat, + greater.states[74].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[27].cn0 = 205; - test_msg.states[27].mesid.code = 1; - test_msg.states[27].mesid.sat = 10; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[75].cn0, greater.states[75].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[75].mesid.code, + greater.states[75].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[75].mesid.sat, + greater.states[75].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[28].cn0 = 0; - test_msg.states[28].mesid.code = 0; - test_msg.states[28].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[76].cn0, greater.states[76].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[76].mesid.code, + greater.states[76].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[76].mesid.sat, + greater.states[76].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[29].cn0 = 230; - test_msg.states[29].mesid.code = 3; - test_msg.states[29].mesid.sat = 96; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[77].cn0, greater.states[77].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[77].mesid.code, + greater.states[77].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[77].mesid.sat, + greater.states[77].mesid.sat); + comparison_tests(lesser, greater); + } - test_msg.states[30].cn0 = 0; - test_msg.states[30].mesid.code = 0; - test_msg.states[30].mesid.sat = 0; + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[78].cn0, greater.states[78].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[78].mesid.code, + greater.states[78].mesid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_measurement_state_t lesser = info.test_msg; + sbp_msg_measurement_state_t greater = info.test_msg; + make_lesser_greater(lesser.states[78].mesid.sat, + greater.states[78].mesid.sat); + comparison_tests(lesser, greater); + } +} - test_msg.states[31].cn0 = 214; - test_msg.states[31].mesid.code = 3; - test_msg.states[31].mesid.sat = 101; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgMeasurementState); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_MEASUREMENT_STATE"); +} - test_msg.states[32].cn0 = 212; - test_msg.states[32].mesid.code = 3; - test_msg.states[32].mesid.sat = 103; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.states[33].cn0 = 209; - test_msg.states[33].mesid.code = 3; - test_msg.states[33].mesid.sat = 104; + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; - test_msg.states[34].cn0 = 157; - test_msg.states[34].mesid.code = 3; - test_msg.states[34].mesid.sat = 106; + const sbp_msg_measurement_state_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_measurement_state_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - test_msg.states[35].cn0 = 230; - test_msg.states[35].mesid.code = 3; - test_msg.states[35].mesid.sat = 102; + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} - test_msg.states[36].cn0 = 0; - test_msg.states[36].mesid.code = 0; - test_msg.states[36].mesid.sat = 0; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - test_msg.states[37].cn0 = 0; - test_msg.states[37].mesid.code = 0; - test_msg.states[37].mesid.sat = 0; + sbp_msg_t msg1 = sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.measurement_state, info.test_msg); - test_msg.states[38].cn0 = 189; - test_msg.states[38].mesid.code = 4; - test_msg.states[38].mesid.sat = 101; + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.measurement_state, info.test_msg); +} - test_msg.states[39].cn0 = 207; - test_msg.states[39].mesid.code = 4; - test_msg.states[39].mesid.sat = 96; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} - test_msg.states[40].cn0 = 164; - test_msg.states[40].mesid.code = 4; - test_msg.states[40].mesid.sat = 106; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); - test_msg.states[41].cn0 = 193; - test_msg.states[41].mesid.code = 4; - test_msg.states[41].mesid.sat = 104; + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); - test_msg.states[42].cn0 = 0; - test_msg.states[42].mesid.code = 0; - test_msg.states[42].mesid.sat = 0; + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - test_msg.states[43].cn0 = 208; - test_msg.states[43].mesid.code = 4; - test_msg.states[43].mesid.sat = 102; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[237]; + uint8_t n_written; - test_msg.states[44].cn0 = 0; - test_msg.states[44].mesid.code = 0; - test_msg.states[44].mesid.sat = 0; + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 237); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 237), 0); +} - test_msg.states[45].cn0 = 212; - test_msg.states[45].mesid.code = 12; - test_msg.states[45].mesid.sat = 27; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_measurement_state_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 237); + EXPECT_EQ(msg, info.test_msg); +} - test_msg.states[46].cn0 = 161; - test_msg.states[46].mesid.code = 12; - test_msg.states[46].mesid.sat = 29; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); - test_msg.states[47].cn0 = 216; - test_msg.states[47].mesid.code = 12; - test_msg.states[47].mesid.sat = 32; + sbp::State state{}; + state.set_reader(&reader); - test_msg.states[48].cn0 = 216; - test_msg.states[48].mesid.code = 12; - test_msg.states[48].mesid.sat = 30; + CppHandler handler{&state}; - test_msg.states[49].cn0 = 178; - test_msg.states[49].mesid.code = 12; - test_msg.states[49].mesid.sat = 20; + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } - test_msg.states[50].cn0 = 0; - test_msg.states[50].mesid.code = 0; - test_msg.states[50].mesid.sat = 0; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.states[51].cn0 = 0; - test_msg.states[51].mesid.code = 0; - test_msg.states[51].mesid.sat = 0; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); - test_msg.states[52].cn0 = 0; - test_msg.states[52].mesid.code = 0; - test_msg.states[52].mesid.sat = 0; + state.process_message(info.sender_id, SbpMsgMeasurementState, + &info.test_msg_wrapped); - test_msg.states[53].cn0 = 0; - test_msg.states[53].mesid.code = 0; - test_msg.states[53].mesid.sat = 0; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} - test_msg.states[54].cn0 = 0; - test_msg.states[54].mesid.code = 0; - test_msg.states[54].mesid.sat = 0; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); - test_msg.states[55].cn0 = 0; - test_msg.states[55].mesid.code = 0; - test_msg.states[55].mesid.sat = 0; + sbp::State state{}; + state.set_writer(&writer); - test_msg.states[56].cn0 = 0; - test_msg.states[56].mesid.code = 0; - test_msg.states[56].mesid.sat = 0; + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - test_msg.states[57].cn0 = 0; - test_msg.states[57].mesid.code = 0; - test_msg.states[57].mesid.sat = 0; +TEST_F(Testauto_check_sbp_tracking_MsgMeasurementState0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); - test_msg.states[58].cn0 = 0; - test_msg.states[58].mesid.code = 0; - test_msg.states[58].mesid.sat = 0; + sbp::State state{}; + state.set_writer(&writer); - test_msg.states[59].cn0 = 0; - test_msg.states[59].mesid.code = 0; - test_msg.states[59].mesid.sat = 0; - - test_msg.states[60].cn0 = 0; - test_msg.states[60].mesid.code = 0; - test_msg.states[60].mesid.sat = 0; - - test_msg.states[61].cn0 = 0; - test_msg.states[61].mesid.code = 0; - test_msg.states[61].mesid.sat = 0; - - test_msg.states[62].cn0 = 0; - test_msg.states[62].mesid.code = 0; - test_msg.states[62].mesid.sat = 0; - - test_msg.states[63].cn0 = 203; - test_msg.states[63].mesid.code = 14; - test_msg.states[63].mesid.sat = 36; - - test_msg.states[64].cn0 = 0; - test_msg.states[64].mesid.code = 0; - test_msg.states[64].mesid.sat = 0; - - test_msg.states[65].cn0 = 158; - test_msg.states[65].mesid.code = 14; - test_msg.states[65].mesid.sat = 5; - - test_msg.states[66].cn0 = 194; - test_msg.states[66].mesid.code = 14; - test_msg.states[66].mesid.sat = 4; - - test_msg.states[67].cn0 = 192; - test_msg.states[67].mesid.code = 14; - test_msg.states[67].mesid.sat = 11; - - test_msg.states[68].cn0 = 207; - test_msg.states[68].mesid.code = 14; - test_msg.states[68].mesid.sat = 9; - - test_msg.states[69].cn0 = 0; - test_msg.states[69].mesid.code = 0; - test_msg.states[69].mesid.sat = 0; - - test_msg.states[70].cn0 = 0; - test_msg.states[70].mesid.code = 0; - test_msg.states[70].mesid.sat = 0; - - test_msg.states[71].cn0 = 0; - test_msg.states[71].mesid.code = 0; - test_msg.states[71].mesid.sat = 0; - - test_msg.states[72].cn0 = 218; - test_msg.states[72].mesid.code = 20; - test_msg.states[72].mesid.sat = 9; - - test_msg.states[73].cn0 = 176; - test_msg.states[73].mesid.code = 20; - test_msg.states[73].mesid.sat = 5; - - test_msg.states[74].cn0 = 217; - test_msg.states[74].mesid.code = 20; - test_msg.states[74].mesid.sat = 36; - - test_msg.states[75].cn0 = 200; - test_msg.states[75].mesid.code = 20; - test_msg.states[75].mesid.sat = 11; - - test_msg.states[76].cn0 = 205; - test_msg.states[76].mesid.code = 20; - test_msg.states[76].mesid.sat = 4; - - test_msg.states[77].cn0 = 0; - test_msg.states[77].mesid.code = 0; - test_msg.states[77].mesid.sat = 0; - - test_msg.states[78].cn0 = 0; - test_msg.states[78].mesid.code = 0; - test_msg.states[78].mesid.sat = 0; - - EXPECT_EQ(send_message(31183, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 31183); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 79) - << "incorrect value for last_msg_.n_states, expected 79, is " - << last_msg_.n_states; - EXPECT_EQ(last_msg_.states[0].cn0, 162) - << "incorrect value for last_msg_.states[0].cn0, expected 162, is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].mesid.code, 0) - << "incorrect value for last_msg_.states[0].mesid.code, expected 0, is " - << last_msg_.states[0].mesid.code; - EXPECT_EQ(last_msg_.states[0].mesid.sat, 29) - << "incorrect value for last_msg_.states[0].mesid.sat, expected 29, is " - << last_msg_.states[0].mesid.sat; - EXPECT_EQ(last_msg_.states[1].cn0, 0) - << "incorrect value for last_msg_.states[1].cn0, expected 0, is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].mesid.code, 0) - << "incorrect value for last_msg_.states[1].mesid.code, expected 0, is " - << last_msg_.states[1].mesid.code; - EXPECT_EQ(last_msg_.states[1].mesid.sat, 0) - << "incorrect value for last_msg_.states[1].mesid.sat, expected 0, is " - << last_msg_.states[1].mesid.sat; - EXPECT_EQ(last_msg_.states[2].cn0, 0) - << "incorrect value for last_msg_.states[2].cn0, expected 0, is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].mesid.code, 0) - << "incorrect value for last_msg_.states[2].mesid.code, expected 0, is " - << last_msg_.states[2].mesid.code; - EXPECT_EQ(last_msg_.states[2].mesid.sat, 0) - << "incorrect value for last_msg_.states[2].mesid.sat, expected 0, is " - << last_msg_.states[2].mesid.sat; - EXPECT_EQ(last_msg_.states[3].cn0, 201) - << "incorrect value for last_msg_.states[3].cn0, expected 201, is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].mesid.code, 0) - << "incorrect value for last_msg_.states[3].mesid.code, expected 0, is " - << last_msg_.states[3].mesid.code; - EXPECT_EQ(last_msg_.states[3].mesid.sat, 27) - << "incorrect value for last_msg_.states[3].mesid.sat, expected 27, is " - << last_msg_.states[3].mesid.sat; - EXPECT_EQ(last_msg_.states[4].cn0, 168) - << "incorrect value for last_msg_.states[4].cn0, expected 168, is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].mesid.code, 0) - << "incorrect value for last_msg_.states[4].mesid.code, expected 0, is " - << last_msg_.states[4].mesid.code; - EXPECT_EQ(last_msg_.states[4].mesid.sat, 20) - << "incorrect value for last_msg_.states[4].mesid.sat, expected 20, is " - << last_msg_.states[4].mesid.sat; - EXPECT_EQ(last_msg_.states[5].cn0, 184) - << "incorrect value for last_msg_.states[5].cn0, expected 184, is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].mesid.code, 0) - << "incorrect value for last_msg_.states[5].mesid.code, expected 0, is " - << last_msg_.states[5].mesid.code; - EXPECT_EQ(last_msg_.states[5].mesid.sat, 32) - << "incorrect value for last_msg_.states[5].mesid.sat, expected 32, is " - << last_msg_.states[5].mesid.sat; - EXPECT_EQ(last_msg_.states[6].cn0, 187) - << "incorrect value for last_msg_.states[6].cn0, expected 187, is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].mesid.code, 0) - << "incorrect value for last_msg_.states[6].mesid.code, expected 0, is " - << last_msg_.states[6].mesid.code; - EXPECT_EQ(last_msg_.states[6].mesid.sat, 15) - << "incorrect value for last_msg_.states[6].mesid.sat, expected 15, is " - << last_msg_.states[6].mesid.sat; - EXPECT_EQ(last_msg_.states[7].cn0, 0) - << "incorrect value for last_msg_.states[7].cn0, expected 0, is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].mesid.code, 0) - << "incorrect value for last_msg_.states[7].mesid.code, expected 0, is " - << last_msg_.states[7].mesid.code; - EXPECT_EQ(last_msg_.states[7].mesid.sat, 0) - << "incorrect value for last_msg_.states[7].mesid.sat, expected 0, is " - << last_msg_.states[7].mesid.sat; - EXPECT_EQ(last_msg_.states[8].cn0, 210) - << "incorrect value for last_msg_.states[8].cn0, expected 210, is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].mesid.code, 0) - << "incorrect value for last_msg_.states[8].mesid.code, expected 0, is " - << last_msg_.states[8].mesid.code; - EXPECT_EQ(last_msg_.states[8].mesid.sat, 18) - << "incorrect value for last_msg_.states[8].mesid.sat, expected 18, is " - << last_msg_.states[8].mesid.sat; - EXPECT_EQ(last_msg_.states[9].cn0, 167) - << "incorrect value for last_msg_.states[9].cn0, expected 167, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].mesid.code, 0) - << "incorrect value for last_msg_.states[9].mesid.code, expected 0, is " - << last_msg_.states[9].mesid.code; - EXPECT_EQ(last_msg_.states[9].mesid.sat, 16) - << "incorrect value for last_msg_.states[9].mesid.sat, expected 16, is " - << last_msg_.states[9].mesid.sat; - EXPECT_EQ(last_msg_.states[10].cn0, 0) - << "incorrect value for last_msg_.states[10].cn0, expected 0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].mesid.code, 0) - << "incorrect value for last_msg_.states[10].mesid.code, expected 0, is " - << last_msg_.states[10].mesid.code; - EXPECT_EQ(last_msg_.states[10].mesid.sat, 0) - << "incorrect value for last_msg_.states[10].mesid.sat, expected 0, is " - << last_msg_.states[10].mesid.sat; - EXPECT_EQ(last_msg_.states[11].cn0, 213) - << "incorrect value for last_msg_.states[11].cn0, expected 213, is " - << last_msg_.states[11].cn0; - EXPECT_EQ(last_msg_.states[11].mesid.code, 0) - << "incorrect value for last_msg_.states[11].mesid.code, expected 0, is " - << last_msg_.states[11].mesid.code; - EXPECT_EQ(last_msg_.states[11].mesid.sat, 23) - << "incorrect value for last_msg_.states[11].mesid.sat, expected 23, is " - << last_msg_.states[11].mesid.sat; - EXPECT_EQ(last_msg_.states[12].cn0, 223) - << "incorrect value for last_msg_.states[12].cn0, expected 223, is " - << last_msg_.states[12].cn0; - EXPECT_EQ(last_msg_.states[12].mesid.code, 0) - << "incorrect value for last_msg_.states[12].mesid.code, expected 0, is " - << last_msg_.states[12].mesid.code; - EXPECT_EQ(last_msg_.states[12].mesid.sat, 10) - << "incorrect value for last_msg_.states[12].mesid.sat, expected 10, is " - << last_msg_.states[12].mesid.sat; - EXPECT_EQ(last_msg_.states[13].cn0, 0) - << "incorrect value for last_msg_.states[13].cn0, expected 0, is " - << last_msg_.states[13].cn0; - EXPECT_EQ(last_msg_.states[13].mesid.code, 0) - << "incorrect value for last_msg_.states[13].mesid.code, expected 0, is " - << last_msg_.states[13].mesid.code; - EXPECT_EQ(last_msg_.states[13].mesid.sat, 0) - << "incorrect value for last_msg_.states[13].mesid.sat, expected 0, is " - << last_msg_.states[13].mesid.sat; - EXPECT_EQ(last_msg_.states[14].cn0, 0) - << "incorrect value for last_msg_.states[14].cn0, expected 0, is " - << last_msg_.states[14].cn0; - EXPECT_EQ(last_msg_.states[14].mesid.code, 0) - << "incorrect value for last_msg_.states[14].mesid.code, expected 0, is " - << last_msg_.states[14].mesid.code; - EXPECT_EQ(last_msg_.states[14].mesid.sat, 0) - << "incorrect value for last_msg_.states[14].mesid.sat, expected 0, is " - << last_msg_.states[14].mesid.sat; - EXPECT_EQ(last_msg_.states[15].cn0, 0) - << "incorrect value for last_msg_.states[15].cn0, expected 0, is " - << last_msg_.states[15].cn0; - EXPECT_EQ(last_msg_.states[15].mesid.code, 0) - << "incorrect value for last_msg_.states[15].mesid.code, expected 0, is " - << last_msg_.states[15].mesid.code; - EXPECT_EQ(last_msg_.states[15].mesid.sat, 0) - << "incorrect value for last_msg_.states[15].mesid.sat, expected 0, is " - << last_msg_.states[15].mesid.sat; - EXPECT_EQ(last_msg_.states[16].cn0, 0) - << "incorrect value for last_msg_.states[16].cn0, expected 0, is " - << last_msg_.states[16].cn0; - EXPECT_EQ(last_msg_.states[16].mesid.code, 0) - << "incorrect value for last_msg_.states[16].mesid.code, expected 0, is " - << last_msg_.states[16].mesid.code; - EXPECT_EQ(last_msg_.states[16].mesid.sat, 0) - << "incorrect value for last_msg_.states[16].mesid.sat, expected 0, is " - << last_msg_.states[16].mesid.sat; - EXPECT_EQ(last_msg_.states[17].cn0, 202) - << "incorrect value for last_msg_.states[17].cn0, expected 202, is " - << last_msg_.states[17].cn0; - EXPECT_EQ(last_msg_.states[17].mesid.code, 2) - << "incorrect value for last_msg_.states[17].mesid.code, expected 2, is " - << last_msg_.states[17].mesid.code; - EXPECT_EQ(last_msg_.states[17].mesid.sat, 131) - << "incorrect value for last_msg_.states[17].mesid.sat, expected 131, is " - << last_msg_.states[17].mesid.sat; - EXPECT_EQ(last_msg_.states[18].cn0, 192) - << "incorrect value for last_msg_.states[18].cn0, expected 192, is " - << last_msg_.states[18].cn0; - EXPECT_EQ(last_msg_.states[18].mesid.code, 1) - << "incorrect value for last_msg_.states[18].mesid.code, expected 1, is " - << last_msg_.states[18].mesid.code; - EXPECT_EQ(last_msg_.states[18].mesid.sat, 27) - << "incorrect value for last_msg_.states[18].mesid.sat, expected 27, is " - << last_msg_.states[18].mesid.sat; - EXPECT_EQ(last_msg_.states[19].cn0, 165) - << "incorrect value for last_msg_.states[19].cn0, expected 165, is " - << last_msg_.states[19].cn0; - EXPECT_EQ(last_msg_.states[19].mesid.code, 1) - << "incorrect value for last_msg_.states[19].mesid.code, expected 1, is " - << last_msg_.states[19].mesid.code; - EXPECT_EQ(last_msg_.states[19].mesid.sat, 15) - << "incorrect value for last_msg_.states[19].mesid.sat, expected 15, is " - << last_msg_.states[19].mesid.sat; - EXPECT_EQ(last_msg_.states[20].cn0, 146) - << "incorrect value for last_msg_.states[20].cn0, expected 146, is " - << last_msg_.states[20].cn0; - EXPECT_EQ(last_msg_.states[20].mesid.code, 1) - << "incorrect value for last_msg_.states[20].mesid.code, expected 1, is " - << last_msg_.states[20].mesid.code; - EXPECT_EQ(last_msg_.states[20].mesid.sat, 29) - << "incorrect value for last_msg_.states[20].mesid.sat, expected 29, is " - << last_msg_.states[20].mesid.sat; - EXPECT_EQ(last_msg_.states[21].cn0, 170) - << "incorrect value for last_msg_.states[21].cn0, expected 170, is " - << last_msg_.states[21].cn0; - EXPECT_EQ(last_msg_.states[21].mesid.code, 1) - << "incorrect value for last_msg_.states[21].mesid.code, expected 1, is " - << last_msg_.states[21].mesid.code; - EXPECT_EQ(last_msg_.states[21].mesid.sat, 32) - << "incorrect value for last_msg_.states[21].mesid.sat, expected 32, is " - << last_msg_.states[21].mesid.sat; - EXPECT_EQ(last_msg_.states[22].cn0, 201) - << "incorrect value for last_msg_.states[22].cn0, expected 201, is " - << last_msg_.states[22].cn0; - EXPECT_EQ(last_msg_.states[22].mesid.code, 1) - << "incorrect value for last_msg_.states[22].mesid.code, expected 1, is " - << last_msg_.states[22].mesid.code; - EXPECT_EQ(last_msg_.states[22].mesid.sat, 18) - << "incorrect value for last_msg_.states[22].mesid.sat, expected 18, is " - << last_msg_.states[22].mesid.sat; - EXPECT_EQ(last_msg_.states[23].cn0, 0) - << "incorrect value for last_msg_.states[23].cn0, expected 0, is " - << last_msg_.states[23].cn0; - EXPECT_EQ(last_msg_.states[23].mesid.code, 0) - << "incorrect value for last_msg_.states[23].mesid.code, expected 0, is " - << last_msg_.states[23].mesid.code; - EXPECT_EQ(last_msg_.states[23].mesid.sat, 0) - << "incorrect value for last_msg_.states[23].mesid.sat, expected 0, is " - << last_msg_.states[23].mesid.sat; - EXPECT_EQ(last_msg_.states[24].cn0, 0) - << "incorrect value for last_msg_.states[24].cn0, expected 0, is " - << last_msg_.states[24].cn0; - EXPECT_EQ(last_msg_.states[24].mesid.code, 0) - << "incorrect value for last_msg_.states[24].mesid.code, expected 0, is " - << last_msg_.states[24].mesid.code; - EXPECT_EQ(last_msg_.states[24].mesid.sat, 0) - << "incorrect value for last_msg_.states[24].mesid.sat, expected 0, is " - << last_msg_.states[24].mesid.sat; - EXPECT_EQ(last_msg_.states[25].cn0, 0) - << "incorrect value for last_msg_.states[25].cn0, expected 0, is " - << last_msg_.states[25].cn0; - EXPECT_EQ(last_msg_.states[25].mesid.code, 0) - << "incorrect value for last_msg_.states[25].mesid.code, expected 0, is " - << last_msg_.states[25].mesid.code; - EXPECT_EQ(last_msg_.states[25].mesid.sat, 0) - << "incorrect value for last_msg_.states[25].mesid.sat, expected 0, is " - << last_msg_.states[25].mesid.sat; - EXPECT_EQ(last_msg_.states[26].cn0, 212) - << "incorrect value for last_msg_.states[26].cn0, expected 212, is " - << last_msg_.states[26].cn0; - EXPECT_EQ(last_msg_.states[26].mesid.code, 1) - << "incorrect value for last_msg_.states[26].mesid.code, expected 1, is " - << last_msg_.states[26].mesid.code; - EXPECT_EQ(last_msg_.states[26].mesid.sat, 23) - << "incorrect value for last_msg_.states[26].mesid.sat, expected 23, is " - << last_msg_.states[26].mesid.sat; - EXPECT_EQ(last_msg_.states[27].cn0, 205) - << "incorrect value for last_msg_.states[27].cn0, expected 205, is " - << last_msg_.states[27].cn0; - EXPECT_EQ(last_msg_.states[27].mesid.code, 1) - << "incorrect value for last_msg_.states[27].mesid.code, expected 1, is " - << last_msg_.states[27].mesid.code; - EXPECT_EQ(last_msg_.states[27].mesid.sat, 10) - << "incorrect value for last_msg_.states[27].mesid.sat, expected 10, is " - << last_msg_.states[27].mesid.sat; - EXPECT_EQ(last_msg_.states[28].cn0, 0) - << "incorrect value for last_msg_.states[28].cn0, expected 0, is " - << last_msg_.states[28].cn0; - EXPECT_EQ(last_msg_.states[28].mesid.code, 0) - << "incorrect value for last_msg_.states[28].mesid.code, expected 0, is " - << last_msg_.states[28].mesid.code; - EXPECT_EQ(last_msg_.states[28].mesid.sat, 0) - << "incorrect value for last_msg_.states[28].mesid.sat, expected 0, is " - << last_msg_.states[28].mesid.sat; - EXPECT_EQ(last_msg_.states[29].cn0, 230) - << "incorrect value for last_msg_.states[29].cn0, expected 230, is " - << last_msg_.states[29].cn0; - EXPECT_EQ(last_msg_.states[29].mesid.code, 3) - << "incorrect value for last_msg_.states[29].mesid.code, expected 3, is " - << last_msg_.states[29].mesid.code; - EXPECT_EQ(last_msg_.states[29].mesid.sat, 96) - << "incorrect value for last_msg_.states[29].mesid.sat, expected 96, is " - << last_msg_.states[29].mesid.sat; - EXPECT_EQ(last_msg_.states[30].cn0, 0) - << "incorrect value for last_msg_.states[30].cn0, expected 0, is " - << last_msg_.states[30].cn0; - EXPECT_EQ(last_msg_.states[30].mesid.code, 0) - << "incorrect value for last_msg_.states[30].mesid.code, expected 0, is " - << last_msg_.states[30].mesid.code; - EXPECT_EQ(last_msg_.states[30].mesid.sat, 0) - << "incorrect value for last_msg_.states[30].mesid.sat, expected 0, is " - << last_msg_.states[30].mesid.sat; - EXPECT_EQ(last_msg_.states[31].cn0, 214) - << "incorrect value for last_msg_.states[31].cn0, expected 214, is " - << last_msg_.states[31].cn0; - EXPECT_EQ(last_msg_.states[31].mesid.code, 3) - << "incorrect value for last_msg_.states[31].mesid.code, expected 3, is " - << last_msg_.states[31].mesid.code; - EXPECT_EQ(last_msg_.states[31].mesid.sat, 101) - << "incorrect value for last_msg_.states[31].mesid.sat, expected 101, is " - << last_msg_.states[31].mesid.sat; - EXPECT_EQ(last_msg_.states[32].cn0, 212) - << "incorrect value for last_msg_.states[32].cn0, expected 212, is " - << last_msg_.states[32].cn0; - EXPECT_EQ(last_msg_.states[32].mesid.code, 3) - << "incorrect value for last_msg_.states[32].mesid.code, expected 3, is " - << last_msg_.states[32].mesid.code; - EXPECT_EQ(last_msg_.states[32].mesid.sat, 103) - << "incorrect value for last_msg_.states[32].mesid.sat, expected 103, is " - << last_msg_.states[32].mesid.sat; - EXPECT_EQ(last_msg_.states[33].cn0, 209) - << "incorrect value for last_msg_.states[33].cn0, expected 209, is " - << last_msg_.states[33].cn0; - EXPECT_EQ(last_msg_.states[33].mesid.code, 3) - << "incorrect value for last_msg_.states[33].mesid.code, expected 3, is " - << last_msg_.states[33].mesid.code; - EXPECT_EQ(last_msg_.states[33].mesid.sat, 104) - << "incorrect value for last_msg_.states[33].mesid.sat, expected 104, is " - << last_msg_.states[33].mesid.sat; - EXPECT_EQ(last_msg_.states[34].cn0, 157) - << "incorrect value for last_msg_.states[34].cn0, expected 157, is " - << last_msg_.states[34].cn0; - EXPECT_EQ(last_msg_.states[34].mesid.code, 3) - << "incorrect value for last_msg_.states[34].mesid.code, expected 3, is " - << last_msg_.states[34].mesid.code; - EXPECT_EQ(last_msg_.states[34].mesid.sat, 106) - << "incorrect value for last_msg_.states[34].mesid.sat, expected 106, is " - << last_msg_.states[34].mesid.sat; - EXPECT_EQ(last_msg_.states[35].cn0, 230) - << "incorrect value for last_msg_.states[35].cn0, expected 230, is " - << last_msg_.states[35].cn0; - EXPECT_EQ(last_msg_.states[35].mesid.code, 3) - << "incorrect value for last_msg_.states[35].mesid.code, expected 3, is " - << last_msg_.states[35].mesid.code; - EXPECT_EQ(last_msg_.states[35].mesid.sat, 102) - << "incorrect value for last_msg_.states[35].mesid.sat, expected 102, is " - << last_msg_.states[35].mesid.sat; - EXPECT_EQ(last_msg_.states[36].cn0, 0) - << "incorrect value for last_msg_.states[36].cn0, expected 0, is " - << last_msg_.states[36].cn0; - EXPECT_EQ(last_msg_.states[36].mesid.code, 0) - << "incorrect value for last_msg_.states[36].mesid.code, expected 0, is " - << last_msg_.states[36].mesid.code; - EXPECT_EQ(last_msg_.states[36].mesid.sat, 0) - << "incorrect value for last_msg_.states[36].mesid.sat, expected 0, is " - << last_msg_.states[36].mesid.sat; - EXPECT_EQ(last_msg_.states[37].cn0, 0) - << "incorrect value for last_msg_.states[37].cn0, expected 0, is " - << last_msg_.states[37].cn0; - EXPECT_EQ(last_msg_.states[37].mesid.code, 0) - << "incorrect value for last_msg_.states[37].mesid.code, expected 0, is " - << last_msg_.states[37].mesid.code; - EXPECT_EQ(last_msg_.states[37].mesid.sat, 0) - << "incorrect value for last_msg_.states[37].mesid.sat, expected 0, is " - << last_msg_.states[37].mesid.sat; - EXPECT_EQ(last_msg_.states[38].cn0, 189) - << "incorrect value for last_msg_.states[38].cn0, expected 189, is " - << last_msg_.states[38].cn0; - EXPECT_EQ(last_msg_.states[38].mesid.code, 4) - << "incorrect value for last_msg_.states[38].mesid.code, expected 4, is " - << last_msg_.states[38].mesid.code; - EXPECT_EQ(last_msg_.states[38].mesid.sat, 101) - << "incorrect value for last_msg_.states[38].mesid.sat, expected 101, is " - << last_msg_.states[38].mesid.sat; - EXPECT_EQ(last_msg_.states[39].cn0, 207) - << "incorrect value for last_msg_.states[39].cn0, expected 207, is " - << last_msg_.states[39].cn0; - EXPECT_EQ(last_msg_.states[39].mesid.code, 4) - << "incorrect value for last_msg_.states[39].mesid.code, expected 4, is " - << last_msg_.states[39].mesid.code; - EXPECT_EQ(last_msg_.states[39].mesid.sat, 96) - << "incorrect value for last_msg_.states[39].mesid.sat, expected 96, is " - << last_msg_.states[39].mesid.sat; - EXPECT_EQ(last_msg_.states[40].cn0, 164) - << "incorrect value for last_msg_.states[40].cn0, expected 164, is " - << last_msg_.states[40].cn0; - EXPECT_EQ(last_msg_.states[40].mesid.code, 4) - << "incorrect value for last_msg_.states[40].mesid.code, expected 4, is " - << last_msg_.states[40].mesid.code; - EXPECT_EQ(last_msg_.states[40].mesid.sat, 106) - << "incorrect value for last_msg_.states[40].mesid.sat, expected 106, is " - << last_msg_.states[40].mesid.sat; - EXPECT_EQ(last_msg_.states[41].cn0, 193) - << "incorrect value for last_msg_.states[41].cn0, expected 193, is " - << last_msg_.states[41].cn0; - EXPECT_EQ(last_msg_.states[41].mesid.code, 4) - << "incorrect value for last_msg_.states[41].mesid.code, expected 4, is " - << last_msg_.states[41].mesid.code; - EXPECT_EQ(last_msg_.states[41].mesid.sat, 104) - << "incorrect value for last_msg_.states[41].mesid.sat, expected 104, is " - << last_msg_.states[41].mesid.sat; - EXPECT_EQ(last_msg_.states[42].cn0, 0) - << "incorrect value for last_msg_.states[42].cn0, expected 0, is " - << last_msg_.states[42].cn0; - EXPECT_EQ(last_msg_.states[42].mesid.code, 0) - << "incorrect value for last_msg_.states[42].mesid.code, expected 0, is " - << last_msg_.states[42].mesid.code; - EXPECT_EQ(last_msg_.states[42].mesid.sat, 0) - << "incorrect value for last_msg_.states[42].mesid.sat, expected 0, is " - << last_msg_.states[42].mesid.sat; - EXPECT_EQ(last_msg_.states[43].cn0, 208) - << "incorrect value for last_msg_.states[43].cn0, expected 208, is " - << last_msg_.states[43].cn0; - EXPECT_EQ(last_msg_.states[43].mesid.code, 4) - << "incorrect value for last_msg_.states[43].mesid.code, expected 4, is " - << last_msg_.states[43].mesid.code; - EXPECT_EQ(last_msg_.states[43].mesid.sat, 102) - << "incorrect value for last_msg_.states[43].mesid.sat, expected 102, is " - << last_msg_.states[43].mesid.sat; - EXPECT_EQ(last_msg_.states[44].cn0, 0) - << "incorrect value for last_msg_.states[44].cn0, expected 0, is " - << last_msg_.states[44].cn0; - EXPECT_EQ(last_msg_.states[44].mesid.code, 0) - << "incorrect value for last_msg_.states[44].mesid.code, expected 0, is " - << last_msg_.states[44].mesid.code; - EXPECT_EQ(last_msg_.states[44].mesid.sat, 0) - << "incorrect value for last_msg_.states[44].mesid.sat, expected 0, is " - << last_msg_.states[44].mesid.sat; - EXPECT_EQ(last_msg_.states[45].cn0, 212) - << "incorrect value for last_msg_.states[45].cn0, expected 212, is " - << last_msg_.states[45].cn0; - EXPECT_EQ(last_msg_.states[45].mesid.code, 12) - << "incorrect value for last_msg_.states[45].mesid.code, expected 12, is " - << last_msg_.states[45].mesid.code; - EXPECT_EQ(last_msg_.states[45].mesid.sat, 27) - << "incorrect value for last_msg_.states[45].mesid.sat, expected 27, is " - << last_msg_.states[45].mesid.sat; - EXPECT_EQ(last_msg_.states[46].cn0, 161) - << "incorrect value for last_msg_.states[46].cn0, expected 161, is " - << last_msg_.states[46].cn0; - EXPECT_EQ(last_msg_.states[46].mesid.code, 12) - << "incorrect value for last_msg_.states[46].mesid.code, expected 12, is " - << last_msg_.states[46].mesid.code; - EXPECT_EQ(last_msg_.states[46].mesid.sat, 29) - << "incorrect value for last_msg_.states[46].mesid.sat, expected 29, is " - << last_msg_.states[46].mesid.sat; - EXPECT_EQ(last_msg_.states[47].cn0, 216) - << "incorrect value for last_msg_.states[47].cn0, expected 216, is " - << last_msg_.states[47].cn0; - EXPECT_EQ(last_msg_.states[47].mesid.code, 12) - << "incorrect value for last_msg_.states[47].mesid.code, expected 12, is " - << last_msg_.states[47].mesid.code; - EXPECT_EQ(last_msg_.states[47].mesid.sat, 32) - << "incorrect value for last_msg_.states[47].mesid.sat, expected 32, is " - << last_msg_.states[47].mesid.sat; - EXPECT_EQ(last_msg_.states[48].cn0, 216) - << "incorrect value for last_msg_.states[48].cn0, expected 216, is " - << last_msg_.states[48].cn0; - EXPECT_EQ(last_msg_.states[48].mesid.code, 12) - << "incorrect value for last_msg_.states[48].mesid.code, expected 12, is " - << last_msg_.states[48].mesid.code; - EXPECT_EQ(last_msg_.states[48].mesid.sat, 30) - << "incorrect value for last_msg_.states[48].mesid.sat, expected 30, is " - << last_msg_.states[48].mesid.sat; - EXPECT_EQ(last_msg_.states[49].cn0, 178) - << "incorrect value for last_msg_.states[49].cn0, expected 178, is " - << last_msg_.states[49].cn0; - EXPECT_EQ(last_msg_.states[49].mesid.code, 12) - << "incorrect value for last_msg_.states[49].mesid.code, expected 12, is " - << last_msg_.states[49].mesid.code; - EXPECT_EQ(last_msg_.states[49].mesid.sat, 20) - << "incorrect value for last_msg_.states[49].mesid.sat, expected 20, is " - << last_msg_.states[49].mesid.sat; - EXPECT_EQ(last_msg_.states[50].cn0, 0) - << "incorrect value for last_msg_.states[50].cn0, expected 0, is " - << last_msg_.states[50].cn0; - EXPECT_EQ(last_msg_.states[50].mesid.code, 0) - << "incorrect value for last_msg_.states[50].mesid.code, expected 0, is " - << last_msg_.states[50].mesid.code; - EXPECT_EQ(last_msg_.states[50].mesid.sat, 0) - << "incorrect value for last_msg_.states[50].mesid.sat, expected 0, is " - << last_msg_.states[50].mesid.sat; - EXPECT_EQ(last_msg_.states[51].cn0, 0) - << "incorrect value for last_msg_.states[51].cn0, expected 0, is " - << last_msg_.states[51].cn0; - EXPECT_EQ(last_msg_.states[51].mesid.code, 0) - << "incorrect value for last_msg_.states[51].mesid.code, expected 0, is " - << last_msg_.states[51].mesid.code; - EXPECT_EQ(last_msg_.states[51].mesid.sat, 0) - << "incorrect value for last_msg_.states[51].mesid.sat, expected 0, is " - << last_msg_.states[51].mesid.sat; - EXPECT_EQ(last_msg_.states[52].cn0, 0) - << "incorrect value for last_msg_.states[52].cn0, expected 0, is " - << last_msg_.states[52].cn0; - EXPECT_EQ(last_msg_.states[52].mesid.code, 0) - << "incorrect value for last_msg_.states[52].mesid.code, expected 0, is " - << last_msg_.states[52].mesid.code; - EXPECT_EQ(last_msg_.states[52].mesid.sat, 0) - << "incorrect value for last_msg_.states[52].mesid.sat, expected 0, is " - << last_msg_.states[52].mesid.sat; - EXPECT_EQ(last_msg_.states[53].cn0, 0) - << "incorrect value for last_msg_.states[53].cn0, expected 0, is " - << last_msg_.states[53].cn0; - EXPECT_EQ(last_msg_.states[53].mesid.code, 0) - << "incorrect value for last_msg_.states[53].mesid.code, expected 0, is " - << last_msg_.states[53].mesid.code; - EXPECT_EQ(last_msg_.states[53].mesid.sat, 0) - << "incorrect value for last_msg_.states[53].mesid.sat, expected 0, is " - << last_msg_.states[53].mesid.sat; - EXPECT_EQ(last_msg_.states[54].cn0, 0) - << "incorrect value for last_msg_.states[54].cn0, expected 0, is " - << last_msg_.states[54].cn0; - EXPECT_EQ(last_msg_.states[54].mesid.code, 0) - << "incorrect value for last_msg_.states[54].mesid.code, expected 0, is " - << last_msg_.states[54].mesid.code; - EXPECT_EQ(last_msg_.states[54].mesid.sat, 0) - << "incorrect value for last_msg_.states[54].mesid.sat, expected 0, is " - << last_msg_.states[54].mesid.sat; - EXPECT_EQ(last_msg_.states[55].cn0, 0) - << "incorrect value for last_msg_.states[55].cn0, expected 0, is " - << last_msg_.states[55].cn0; - EXPECT_EQ(last_msg_.states[55].mesid.code, 0) - << "incorrect value for last_msg_.states[55].mesid.code, expected 0, is " - << last_msg_.states[55].mesid.code; - EXPECT_EQ(last_msg_.states[55].mesid.sat, 0) - << "incorrect value for last_msg_.states[55].mesid.sat, expected 0, is " - << last_msg_.states[55].mesid.sat; - EXPECT_EQ(last_msg_.states[56].cn0, 0) - << "incorrect value for last_msg_.states[56].cn0, expected 0, is " - << last_msg_.states[56].cn0; - EXPECT_EQ(last_msg_.states[56].mesid.code, 0) - << "incorrect value for last_msg_.states[56].mesid.code, expected 0, is " - << last_msg_.states[56].mesid.code; - EXPECT_EQ(last_msg_.states[56].mesid.sat, 0) - << "incorrect value for last_msg_.states[56].mesid.sat, expected 0, is " - << last_msg_.states[56].mesid.sat; - EXPECT_EQ(last_msg_.states[57].cn0, 0) - << "incorrect value for last_msg_.states[57].cn0, expected 0, is " - << last_msg_.states[57].cn0; - EXPECT_EQ(last_msg_.states[57].mesid.code, 0) - << "incorrect value for last_msg_.states[57].mesid.code, expected 0, is " - << last_msg_.states[57].mesid.code; - EXPECT_EQ(last_msg_.states[57].mesid.sat, 0) - << "incorrect value for last_msg_.states[57].mesid.sat, expected 0, is " - << last_msg_.states[57].mesid.sat; - EXPECT_EQ(last_msg_.states[58].cn0, 0) - << "incorrect value for last_msg_.states[58].cn0, expected 0, is " - << last_msg_.states[58].cn0; - EXPECT_EQ(last_msg_.states[58].mesid.code, 0) - << "incorrect value for last_msg_.states[58].mesid.code, expected 0, is " - << last_msg_.states[58].mesid.code; - EXPECT_EQ(last_msg_.states[58].mesid.sat, 0) - << "incorrect value for last_msg_.states[58].mesid.sat, expected 0, is " - << last_msg_.states[58].mesid.sat; - EXPECT_EQ(last_msg_.states[59].cn0, 0) - << "incorrect value for last_msg_.states[59].cn0, expected 0, is " - << last_msg_.states[59].cn0; - EXPECT_EQ(last_msg_.states[59].mesid.code, 0) - << "incorrect value for last_msg_.states[59].mesid.code, expected 0, is " - << last_msg_.states[59].mesid.code; - EXPECT_EQ(last_msg_.states[59].mesid.sat, 0) - << "incorrect value for last_msg_.states[59].mesid.sat, expected 0, is " - << last_msg_.states[59].mesid.sat; - EXPECT_EQ(last_msg_.states[60].cn0, 0) - << "incorrect value for last_msg_.states[60].cn0, expected 0, is " - << last_msg_.states[60].cn0; - EXPECT_EQ(last_msg_.states[60].mesid.code, 0) - << "incorrect value for last_msg_.states[60].mesid.code, expected 0, is " - << last_msg_.states[60].mesid.code; - EXPECT_EQ(last_msg_.states[60].mesid.sat, 0) - << "incorrect value for last_msg_.states[60].mesid.sat, expected 0, is " - << last_msg_.states[60].mesid.sat; - EXPECT_EQ(last_msg_.states[61].cn0, 0) - << "incorrect value for last_msg_.states[61].cn0, expected 0, is " - << last_msg_.states[61].cn0; - EXPECT_EQ(last_msg_.states[61].mesid.code, 0) - << "incorrect value for last_msg_.states[61].mesid.code, expected 0, is " - << last_msg_.states[61].mesid.code; - EXPECT_EQ(last_msg_.states[61].mesid.sat, 0) - << "incorrect value for last_msg_.states[61].mesid.sat, expected 0, is " - << last_msg_.states[61].mesid.sat; - EXPECT_EQ(last_msg_.states[62].cn0, 0) - << "incorrect value for last_msg_.states[62].cn0, expected 0, is " - << last_msg_.states[62].cn0; - EXPECT_EQ(last_msg_.states[62].mesid.code, 0) - << "incorrect value for last_msg_.states[62].mesid.code, expected 0, is " - << last_msg_.states[62].mesid.code; - EXPECT_EQ(last_msg_.states[62].mesid.sat, 0) - << "incorrect value for last_msg_.states[62].mesid.sat, expected 0, is " - << last_msg_.states[62].mesid.sat; - EXPECT_EQ(last_msg_.states[63].cn0, 203) - << "incorrect value for last_msg_.states[63].cn0, expected 203, is " - << last_msg_.states[63].cn0; - EXPECT_EQ(last_msg_.states[63].mesid.code, 14) - << "incorrect value for last_msg_.states[63].mesid.code, expected 14, is " - << last_msg_.states[63].mesid.code; - EXPECT_EQ(last_msg_.states[63].mesid.sat, 36) - << "incorrect value for last_msg_.states[63].mesid.sat, expected 36, is " - << last_msg_.states[63].mesid.sat; - EXPECT_EQ(last_msg_.states[64].cn0, 0) - << "incorrect value for last_msg_.states[64].cn0, expected 0, is " - << last_msg_.states[64].cn0; - EXPECT_EQ(last_msg_.states[64].mesid.code, 0) - << "incorrect value for last_msg_.states[64].mesid.code, expected 0, is " - << last_msg_.states[64].mesid.code; - EXPECT_EQ(last_msg_.states[64].mesid.sat, 0) - << "incorrect value for last_msg_.states[64].mesid.sat, expected 0, is " - << last_msg_.states[64].mesid.sat; - EXPECT_EQ(last_msg_.states[65].cn0, 158) - << "incorrect value for last_msg_.states[65].cn0, expected 158, is " - << last_msg_.states[65].cn0; - EXPECT_EQ(last_msg_.states[65].mesid.code, 14) - << "incorrect value for last_msg_.states[65].mesid.code, expected 14, is " - << last_msg_.states[65].mesid.code; - EXPECT_EQ(last_msg_.states[65].mesid.sat, 5) - << "incorrect value for last_msg_.states[65].mesid.sat, expected 5, is " - << last_msg_.states[65].mesid.sat; - EXPECT_EQ(last_msg_.states[66].cn0, 194) - << "incorrect value for last_msg_.states[66].cn0, expected 194, is " - << last_msg_.states[66].cn0; - EXPECT_EQ(last_msg_.states[66].mesid.code, 14) - << "incorrect value for last_msg_.states[66].mesid.code, expected 14, is " - << last_msg_.states[66].mesid.code; - EXPECT_EQ(last_msg_.states[66].mesid.sat, 4) - << "incorrect value for last_msg_.states[66].mesid.sat, expected 4, is " - << last_msg_.states[66].mesid.sat; - EXPECT_EQ(last_msg_.states[67].cn0, 192) - << "incorrect value for last_msg_.states[67].cn0, expected 192, is " - << last_msg_.states[67].cn0; - EXPECT_EQ(last_msg_.states[67].mesid.code, 14) - << "incorrect value for last_msg_.states[67].mesid.code, expected 14, is " - << last_msg_.states[67].mesid.code; - EXPECT_EQ(last_msg_.states[67].mesid.sat, 11) - << "incorrect value for last_msg_.states[67].mesid.sat, expected 11, is " - << last_msg_.states[67].mesid.sat; - EXPECT_EQ(last_msg_.states[68].cn0, 207) - << "incorrect value for last_msg_.states[68].cn0, expected 207, is " - << last_msg_.states[68].cn0; - EXPECT_EQ(last_msg_.states[68].mesid.code, 14) - << "incorrect value for last_msg_.states[68].mesid.code, expected 14, is " - << last_msg_.states[68].mesid.code; - EXPECT_EQ(last_msg_.states[68].mesid.sat, 9) - << "incorrect value for last_msg_.states[68].mesid.sat, expected 9, is " - << last_msg_.states[68].mesid.sat; - EXPECT_EQ(last_msg_.states[69].cn0, 0) - << "incorrect value for last_msg_.states[69].cn0, expected 0, is " - << last_msg_.states[69].cn0; - EXPECT_EQ(last_msg_.states[69].mesid.code, 0) - << "incorrect value for last_msg_.states[69].mesid.code, expected 0, is " - << last_msg_.states[69].mesid.code; - EXPECT_EQ(last_msg_.states[69].mesid.sat, 0) - << "incorrect value for last_msg_.states[69].mesid.sat, expected 0, is " - << last_msg_.states[69].mesid.sat; - EXPECT_EQ(last_msg_.states[70].cn0, 0) - << "incorrect value for last_msg_.states[70].cn0, expected 0, is " - << last_msg_.states[70].cn0; - EXPECT_EQ(last_msg_.states[70].mesid.code, 0) - << "incorrect value for last_msg_.states[70].mesid.code, expected 0, is " - << last_msg_.states[70].mesid.code; - EXPECT_EQ(last_msg_.states[70].mesid.sat, 0) - << "incorrect value for last_msg_.states[70].mesid.sat, expected 0, is " - << last_msg_.states[70].mesid.sat; - EXPECT_EQ(last_msg_.states[71].cn0, 0) - << "incorrect value for last_msg_.states[71].cn0, expected 0, is " - << last_msg_.states[71].cn0; - EXPECT_EQ(last_msg_.states[71].mesid.code, 0) - << "incorrect value for last_msg_.states[71].mesid.code, expected 0, is " - << last_msg_.states[71].mesid.code; - EXPECT_EQ(last_msg_.states[71].mesid.sat, 0) - << "incorrect value for last_msg_.states[71].mesid.sat, expected 0, is " - << last_msg_.states[71].mesid.sat; - EXPECT_EQ(last_msg_.states[72].cn0, 218) - << "incorrect value for last_msg_.states[72].cn0, expected 218, is " - << last_msg_.states[72].cn0; - EXPECT_EQ(last_msg_.states[72].mesid.code, 20) - << "incorrect value for last_msg_.states[72].mesid.code, expected 20, is " - << last_msg_.states[72].mesid.code; - EXPECT_EQ(last_msg_.states[72].mesid.sat, 9) - << "incorrect value for last_msg_.states[72].mesid.sat, expected 9, is " - << last_msg_.states[72].mesid.sat; - EXPECT_EQ(last_msg_.states[73].cn0, 176) - << "incorrect value for last_msg_.states[73].cn0, expected 176, is " - << last_msg_.states[73].cn0; - EXPECT_EQ(last_msg_.states[73].mesid.code, 20) - << "incorrect value for last_msg_.states[73].mesid.code, expected 20, is " - << last_msg_.states[73].mesid.code; - EXPECT_EQ(last_msg_.states[73].mesid.sat, 5) - << "incorrect value for last_msg_.states[73].mesid.sat, expected 5, is " - << last_msg_.states[73].mesid.sat; - EXPECT_EQ(last_msg_.states[74].cn0, 217) - << "incorrect value for last_msg_.states[74].cn0, expected 217, is " - << last_msg_.states[74].cn0; - EXPECT_EQ(last_msg_.states[74].mesid.code, 20) - << "incorrect value for last_msg_.states[74].mesid.code, expected 20, is " - << last_msg_.states[74].mesid.code; - EXPECT_EQ(last_msg_.states[74].mesid.sat, 36) - << "incorrect value for last_msg_.states[74].mesid.sat, expected 36, is " - << last_msg_.states[74].mesid.sat; - EXPECT_EQ(last_msg_.states[75].cn0, 200) - << "incorrect value for last_msg_.states[75].cn0, expected 200, is " - << last_msg_.states[75].cn0; - EXPECT_EQ(last_msg_.states[75].mesid.code, 20) - << "incorrect value for last_msg_.states[75].mesid.code, expected 20, is " - << last_msg_.states[75].mesid.code; - EXPECT_EQ(last_msg_.states[75].mesid.sat, 11) - << "incorrect value for last_msg_.states[75].mesid.sat, expected 11, is " - << last_msg_.states[75].mesid.sat; - EXPECT_EQ(last_msg_.states[76].cn0, 205) - << "incorrect value for last_msg_.states[76].cn0, expected 205, is " - << last_msg_.states[76].cn0; - EXPECT_EQ(last_msg_.states[76].mesid.code, 20) - << "incorrect value for last_msg_.states[76].mesid.code, expected 20, is " - << last_msg_.states[76].mesid.code; - EXPECT_EQ(last_msg_.states[76].mesid.sat, 4) - << "incorrect value for last_msg_.states[76].mesid.sat, expected 4, is " - << last_msg_.states[76].mesid.sat; - EXPECT_EQ(last_msg_.states[77].cn0, 0) - << "incorrect value for last_msg_.states[77].cn0, expected 0, is " - << last_msg_.states[77].cn0; - EXPECT_EQ(last_msg_.states[77].mesid.code, 0) - << "incorrect value for last_msg_.states[77].mesid.code, expected 0, is " - << last_msg_.states[77].mesid.code; - EXPECT_EQ(last_msg_.states[77].mesid.sat, 0) - << "incorrect value for last_msg_.states[77].mesid.sat, expected 0, is " - << last_msg_.states[77].mesid.sat; - EXPECT_EQ(last_msg_.states[78].cn0, 0) - << "incorrect value for last_msg_.states[78].cn0, expected 0, is " - << last_msg_.states[78].cn0; - EXPECT_EQ(last_msg_.states[78].mesid.code, 0) - << "incorrect value for last_msg_.states[78].mesid.code, expected 0, is " - << last_msg_.states[78].mesid.code; - EXPECT_EQ(last_msg_.states[78].mesid.sat, 0) - << "incorrect value for last_msg_.states[78].mesid.sat, expected 0, is " - << last_msg_.states[78].mesid.sat; + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgMeasurementState, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_tracking_MsgTrackingState.cc b/c/test/cpp/auto_check_sbp_tracking_MsgTrackingState.cc index 57cdc2a02b..9ca8196712 100644 --- a/c/test/cpp/auto_check_sbp_tracking_MsgTrackingState.cc +++ b/c/test/cpp/auto_check_sbp_tracking_MsgTrackingState.cc @@ -16,1374 +16,4383 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_tracking_MsgTrackingState0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_tracking_MsgTrackingState0 : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingState0() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 39.24782180786133); + assign(test_msg_.states[0].sid.code, 0); + assign(test_msg_.states[0].sid.reserved, 0); + assign(test_msg_.states[0].sid.sat, 202); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 36.09756088256836); + assign(test_msg_.states[1].sid.code, 0); + assign(test_msg_.states[1].sid.reserved, 0); + assign(test_msg_.states[1].sid.sat, 203); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 37.62678527832031); + assign(test_msg_.states[2].sid.code, 0); + assign(test_msg_.states[2].sid.reserved, 0); + assign(test_msg_.states[2].sid.sat, 208); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 39.020729064941406); + assign(test_msg_.states[3].sid.code, 0); + assign(test_msg_.states[3].sid.reserved, 0); + assign(test_msg_.states[3].sid.sat, 212); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 42.03290557861328); + assign(test_msg_.states[4].sid.code, 0); + assign(test_msg_.states[4].sid.reserved, 0); + assign(test_msg_.states[4].sid.sat, 217); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 37.43546676635742); + assign(test_msg_.states[5].sid.code, 0); + assign(test_msg_.states[5].sid.reserved, 0); + assign(test_msg_.states[5].sid.sat, 218); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 38.4229621887207); + assign(test_msg_.states[6].sid.code, 0); + assign(test_msg_.states[6].sid.reserved, 0); + assign(test_msg_.states[6].sid.sat, 220); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 38.91520309448242); + assign(test_msg_.states[7].sid.code, 0); + assign(test_msg_.states[7].sid.reserved, 0); + assign(test_msg_.states[7].sid.sat, 222); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 42.62259292602539); + assign(test_msg_.states[8].sid.code, 0); + assign(test_msg_.states[8].sid.reserved, 0); + assign(test_msg_.states[8].sid.sat, 225); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].sid.code, 0); + assign(test_msg_.states[9].sid.reserved, 0); + assign(test_msg_.states[9].sid.sat, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].sid.code, 0); + assign(test_msg_.states[10].sid.reserved, 0); + assign(test_msg_.states[10].sid.sat, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_b, + sizeof(msg->tracking_state_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x61de; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 99; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_b_t &lesser, + const sbp_msg_tracking_state_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_b_t test_msg_{}; + uint8_t encoded_frame_[99 + 8] = { + 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 197, 253, 28, + 66, 1, 203, 0, 0, 0, 231, 99, 16, 66, 1, 208, 0, 0, + 0, 212, 129, 22, 66, 1, 212, 0, 0, 0, 58, 21, 28, 66, + 1, 217, 0, 0, 0, 178, 33, 40, 66, 1, 218, 0, 0, 0, + 235, 189, 21, 66, 1, 220, 0, 0, 0, 29, 177, 25, 66, 1, + 222, 0, 0, 0, 43, 169, 27, 66, 1, 225, 0, 0, 0, 137, + 125, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 222, 97, + }; + uint8_t encoded_payload_[99] = { + 1, 202, 0, 0, 0, 197, 253, 28, 66, 1, 203, 0, 0, 0, 231, 99, 16, 66, + 1, 208, 0, 0, 0, 212, 129, 22, 66, 1, 212, 0, 0, 0, 58, 21, 28, 66, + 1, 217, 0, 0, 0, 178, 33, 40, 66, 1, 218, 0, 0, 0, 235, 189, 21, 66, + 1, 220, 0, 0, 0, 29, 177, 25, 66, 1, 222, 0, 0, 0, 43, 169, 27, 66, + 1, 225, 0, 0, 0, 137, 125, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + for (uint8_t i = 0; i < 99; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.code, greater.states[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.reserved, + greater.states[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.sat, greater.states[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.code, greater.states[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.reserved, + greater.states[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.sat, greater.states[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.code, greater.states[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.reserved, + greater.states[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.sat, greater.states[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.code, greater.states[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.reserved, + greater.states[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.sat, greater.states[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.code, greater.states[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.reserved, + greater.states[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.sat, greater.states[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.code, greater.states[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.reserved, + greater.states[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.sat, greater.states[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.code, greater.states[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.reserved, + greater.states[6].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.sat, greater.states[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.code, greater.states[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.reserved, + greater.states[7].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.sat, greater.states[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.code, greater.states[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.reserved, + greater.states[8].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.sat, greater.states[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.code, greater.states[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.reserved, + greater.states[9].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.sat, greater.states[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.code, + greater.states[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.reserved, + greater.states[10].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.sat, greater.states[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingState1 : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingState1() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 38.994117736816406); + assign(test_msg_.states[0].sid.code, 0); + assign(test_msg_.states[0].sid.reserved, 0); + assign(test_msg_.states[0].sid.sat, 202); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 34.889801025390625); + assign(test_msg_.states[1].sid.code, 0); + assign(test_msg_.states[1].sid.reserved, 0); + assign(test_msg_.states[1].sid.sat, 203); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 37.44603729248047); + assign(test_msg_.states[2].sid.code, 0); + assign(test_msg_.states[2].sid.reserved, 0); + assign(test_msg_.states[2].sid.sat, 208); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 38.72849655151367); + assign(test_msg_.states[3].sid.code, 0); + assign(test_msg_.states[3].sid.reserved, 0); + assign(test_msg_.states[3].sid.sat, 212); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 41.983219146728516); + assign(test_msg_.states[4].sid.code, 0); + assign(test_msg_.states[4].sid.reserved, 0); + assign(test_msg_.states[4].sid.sat, 217); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 37.46448516845703); + assign(test_msg_.states[5].sid.code, 0); + assign(test_msg_.states[5].sid.reserved, 0); + assign(test_msg_.states[5].sid.sat, 218); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 38.44300079345703); + assign(test_msg_.states[6].sid.code, 0); + assign(test_msg_.states[6].sid.reserved, 0); + assign(test_msg_.states[6].sid.sat, 220); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 39.03423309326172); + assign(test_msg_.states[7].sid.code, 0); + assign(test_msg_.states[7].sid.reserved, 0); + assign(test_msg_.states[7].sid.sat, 222); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 42.89944839477539); + assign(test_msg_.states[8].sid.code, 0); + assign(test_msg_.states[8].sid.reserved, 0); + assign(test_msg_.states[8].sid.sat, 225); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].sid.code, 0); + assign(test_msg_.states[9].sid.reserved, 0); + assign(test_msg_.states[9].sid.sat, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].sid.code, 0); + assign(test_msg_.states[10].sid.reserved, 0); + assign(test_msg_.states[10].sid.sat, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_b, + sizeof(msg->tracking_state_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x1f14; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 99; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_b_t &lesser, + const sbp_msg_tracking_state_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_b_t test_msg_{}; + uint8_t encoded_frame_[99 + 8] = { + 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 250, 249, 27, + 66, 1, 203, 0, 0, 0, 40, 143, 11, 66, 1, 208, 0, 0, + 0, 190, 200, 21, 66, 1, 212, 0, 0, 0, 251, 233, 26, 66, + 1, 217, 0, 0, 0, 209, 238, 39, 66, 1, 218, 0, 0, 0, + 162, 219, 21, 66, 1, 220, 0, 0, 0, 162, 197, 25, 66, 1, + 222, 0, 0, 0, 14, 35, 28, 66, 1, 225, 0, 0, 0, 9, + 153, 43, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 20, 31, + }; + uint8_t encoded_payload_[99] = { + 1, 202, 0, 0, 0, 250, 249, 27, 66, 1, 203, 0, 0, 0, 40, 143, 11, 66, + 1, 208, 0, 0, 0, 190, 200, 21, 66, 1, 212, 0, 0, 0, 251, 233, 26, 66, + 1, 217, 0, 0, 0, 209, 238, 39, 66, 1, 218, 0, 0, 0, 162, 219, 21, 66, + 1, 220, 0, 0, 0, 162, 197, 25, 66, 1, 222, 0, 0, 0, 14, 35, 28, 66, + 1, 225, 0, 0, 0, 9, 153, 43, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + for (uint8_t i = 0; i < 99; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.code, greater.states[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.reserved, + greater.states[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.sat, greater.states[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.code, greater.states[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.reserved, + greater.states[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.sat, greater.states[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.code, greater.states[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.reserved, + greater.states[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.sat, greater.states[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.code, greater.states[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.reserved, + greater.states[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.sat, greater.states[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.code, greater.states[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.reserved, + greater.states[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.sat, greater.states[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.code, greater.states[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.reserved, + greater.states[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.sat, greater.states[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.code, greater.states[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.reserved, + greater.states[6].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.sat, greater.states[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.code, greater.states[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.reserved, + greater.states[7].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.sat, greater.states[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.code, greater.states[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.reserved, + greater.states[8].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.sat, greater.states[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.code, greater.states[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.reserved, + greater.states[9].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.sat, greater.states[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.code, + greater.states[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.reserved, + greater.states[10].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.sat, greater.states[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingState2 : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingState2() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 38.95457077026367); + assign(test_msg_.states[0].sid.code, 0); + assign(test_msg_.states[0].sid.reserved, 0); + assign(test_msg_.states[0].sid.sat, 202); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 35.813316345214844); + assign(test_msg_.states[1].sid.code, 0); + assign(test_msg_.states[1].sid.reserved, 0); + assign(test_msg_.states[1].sid.sat, 203); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 37.553924560546875); + assign(test_msg_.states[2].sid.code, 0); + assign(test_msg_.states[2].sid.reserved, 0); + assign(test_msg_.states[2].sid.sat, 208); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 38.88901901245117); + assign(test_msg_.states[3].sid.code, 0); + assign(test_msg_.states[3].sid.reserved, 0); + assign(test_msg_.states[3].sid.sat, 212); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 42.4013557434082); + assign(test_msg_.states[4].sid.code, 0); + assign(test_msg_.states[4].sid.reserved, 0); + assign(test_msg_.states[4].sid.sat, 217); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 37.63916015625); + assign(test_msg_.states[5].sid.code, 0); + assign(test_msg_.states[5].sid.reserved, 0); + assign(test_msg_.states[5].sid.sat, 218); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 37.919986724853516); + assign(test_msg_.states[6].sid.code, 0); + assign(test_msg_.states[6].sid.reserved, 0); + assign(test_msg_.states[6].sid.sat, 220); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 39.25254440307617); + assign(test_msg_.states[7].sid.code, 0); + assign(test_msg_.states[7].sid.reserved, 0); + assign(test_msg_.states[7].sid.sat, 222); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 42.59827423095703); + assign(test_msg_.states[8].sid.code, 0); + assign(test_msg_.states[8].sid.reserved, 0); + assign(test_msg_.states[8].sid.sat, 225); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].sid.code, 0); + assign(test_msg_.states[9].sid.reserved, 0); + assign(test_msg_.states[9].sid.sat, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].sid.code, 0); + assign(test_msg_.states[10].sid.reserved, 0); + assign(test_msg_.states[10].sid.sat, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_b, + sizeof(msg->tracking_state_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x47e9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 99; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_b_t &lesser, + const sbp_msg_tracking_state_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_b_t test_msg_{}; + uint8_t encoded_frame_[99 + 8] = { + 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 123, 209, 27, + 66, 1, 203, 0, 0, 0, 214, 64, 15, 66, 1, 208, 0, 0, + 0, 56, 55, 22, 66, 1, 212, 0, 0, 0, 91, 142, 27, 66, + 1, 217, 0, 0, 0, 253, 154, 41, 66, 1, 218, 0, 0, 0, + 128, 142, 22, 66, 1, 220, 0, 0, 0, 17, 174, 23, 66, 1, + 222, 0, 0, 0, 155, 2, 29, 66, 1, 225, 0, 0, 0, 162, + 100, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 233, 71, + }; + uint8_t encoded_payload_[99] = { + 1, 202, 0, 0, 0, 123, 209, 27, 66, 1, 203, 0, 0, 0, 214, 64, 15, 66, + 1, 208, 0, 0, 0, 56, 55, 22, 66, 1, 212, 0, 0, 0, 91, 142, 27, 66, + 1, 217, 0, 0, 0, 253, 154, 41, 66, 1, 218, 0, 0, 0, 128, 142, 22, 66, + 1, 220, 0, 0, 0, 17, 174, 23, 66, 1, 222, 0, 0, 0, 155, 2, 29, 66, + 1, 225, 0, 0, 0, 162, 100, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + for (uint8_t i = 0; i < 99; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.code, greater.states[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.reserved, + greater.states[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.sat, greater.states[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.code, greater.states[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.reserved, + greater.states[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.sat, greater.states[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.code, greater.states[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.reserved, + greater.states[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.sat, greater.states[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.code, greater.states[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.reserved, + greater.states[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.sat, greater.states[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.code, greater.states[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.reserved, + greater.states[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.sat, greater.states[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.code, greater.states[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.reserved, + greater.states[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.sat, greater.states[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.code, greater.states[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.reserved, + greater.states[6].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.sat, greater.states[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.code, greater.states[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.reserved, + greater.states[7].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.sat, greater.states[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.code, greater.states[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.reserved, + greater.states[8].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.sat, greater.states[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.code, greater.states[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.reserved, + greater.states[9].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.sat, greater.states[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.code, + greater.states[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.reserved, + greater.states[10].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.sat, greater.states[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingState3 : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingState3() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 39.369598388671875); + assign(test_msg_.states[0].sid.code, 0); + assign(test_msg_.states[0].sid.reserved, 0); + assign(test_msg_.states[0].sid.sat, 202); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 36.52173614501953); + assign(test_msg_.states[1].sid.code, 0); + assign(test_msg_.states[1].sid.reserved, 0); + assign(test_msg_.states[1].sid.sat, 203); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 38.15976333618164); + assign(test_msg_.states[2].sid.code, 0); + assign(test_msg_.states[2].sid.reserved, 0); + assign(test_msg_.states[2].sid.sat, 208); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 39.19989776611328); + assign(test_msg_.states[3].sid.code, 0); + assign(test_msg_.states[3].sid.reserved, 0); + assign(test_msg_.states[3].sid.sat, 212); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 41.55845642089844); + assign(test_msg_.states[4].sid.code, 0); + assign(test_msg_.states[4].sid.reserved, 0); + assign(test_msg_.states[4].sid.sat, 217); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 37.026981353759766); + assign(test_msg_.states[5].sid.code, 0); + assign(test_msg_.states[5].sid.reserved, 0); + assign(test_msg_.states[5].sid.sat, 218); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 38.1049690246582); + assign(test_msg_.states[6].sid.code, 0); + assign(test_msg_.states[6].sid.reserved, 0); + assign(test_msg_.states[6].sid.sat, 220); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 39.04584503173828); + assign(test_msg_.states[7].sid.code, 0); + assign(test_msg_.states[7].sid.reserved, 0); + assign(test_msg_.states[7].sid.sat, 222); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 42.37783432006836); + assign(test_msg_.states[8].sid.code, 0); + assign(test_msg_.states[8].sid.reserved, 0); + assign(test_msg_.states[8].sid.sat, 225); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].sid.code, 0); + assign(test_msg_.states[9].sid.reserved, 0); + assign(test_msg_.states[9].sid.sat, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].sid.code, 0); + assign(test_msg_.states[10].sid.reserved, 0); + assign(test_msg_.states[10].sid.sat, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepB, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_b, + sizeof(msg->tracking_state_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0xc149; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 99; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_b_t &lesser, + const sbp_msg_tracking_state_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_b_t test_msg_{}; + uint8_t encoded_frame_[99 + 8] = { + 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 120, 122, 29, + 66, 1, 203, 0, 0, 0, 66, 22, 18, 66, 1, 208, 0, 0, + 0, 153, 163, 24, 66, 1, 212, 0, 0, 0, 178, 204, 28, 66, + 1, 217, 0, 0, 0, 220, 59, 38, 66, 1, 218, 0, 0, 0, + 161, 27, 20, 66, 1, 220, 0, 0, 0, 125, 107, 24, 66, 1, + 222, 0, 0, 0, 242, 46, 28, 66, 1, 225, 0, 0, 0, 231, + 130, 41, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, + 0, 0, 0, 0, 0, 128, 191, 73, 193, + }; + uint8_t encoded_payload_[99] = { + 1, 202, 0, 0, 0, 120, 122, 29, 66, 1, 203, 0, 0, 0, 66, 22, 18, 66, + 1, 208, 0, 0, 0, 153, 163, 24, 66, 1, 212, 0, 0, 0, 178, 204, 28, 66, + 1, 217, 0, 0, 0, 220, 59, 38, 66, 1, 218, 0, 0, 0, 161, 27, 20, 66, + 1, 220, 0, 0, 0, 125, 107, 24, 66, 1, 222, 0, 0, 0, 242, 46, 28, 66, + 1, 225, 0, 0, 0, 231, 130, 41, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + for (uint8_t i = 0; i < 99; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.code, greater.states[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.reserved, + greater.states[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.sat, greater.states[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.code, greater.states[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.reserved, + greater.states[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.sat, greater.states[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.code, greater.states[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.reserved, + greater.states[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.sat, greater.states[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.code, greater.states[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.reserved, + greater.states[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.sat, greater.states[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.code, greater.states[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.reserved, + greater.states[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.sat, greater.states[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.code, greater.states[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.reserved, + greater.states[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.sat, greater.states[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.code, greater.states[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.reserved, + greater.states[6].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.sat, greater.states[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.code, greater.states[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.reserved, + greater.states[7].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.sat, greater.states[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.code, greater.states[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.reserved, + greater.states[8].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.sat, greater.states[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.code, greater.states[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.reserved, + greater.states[9].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.sat, greater.states[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.code, + greater.states[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.reserved, + greater.states[10].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.sat, greater.states[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_b, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingState4 : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgTrackingState0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgTrackingState4() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 39.70351791381836); + assign(test_msg_.states[0].sid.code, 0); + assign(test_msg_.states[0].sid.reserved, 0); + assign(test_msg_.states[0].sid.sat, 202); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 36.52388381958008); + assign(test_msg_.states[1].sid.code, 0); + assign(test_msg_.states[1].sid.reserved, 0); + assign(test_msg_.states[1].sid.sat, 203); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 37.169708251953125); + assign(test_msg_.states[2].sid.code, 0); + assign(test_msg_.states[2].sid.reserved, 0); + assign(test_msg_.states[2].sid.sat, 208); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 38.81692886352539); + assign(test_msg_.states[3].sid.code, 0); + assign(test_msg_.states[3].sid.reserved, 0); + assign(test_msg_.states[3].sid.sat, 212); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 42.05073165893555); + assign(test_msg_.states[4].sid.code, 0); + assign(test_msg_.states[4].sid.reserved, 0); + assign(test_msg_.states[4].sid.sat, 217); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 37.807498931884766); + assign(test_msg_.states[5].sid.code, 0); + assign(test_msg_.states[5].sid.reserved, 0); + assign(test_msg_.states[5].sid.sat, 218); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 37.71632385253906); + assign(test_msg_.states[6].sid.code, 0); + assign(test_msg_.states[6].sid.reserved, 0); + assign(test_msg_.states[6].sid.sat, 220); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 38.5289192199707); + assign(test_msg_.states[7].sid.code, 0); + assign(test_msg_.states[7].sid.reserved, 0); + assign(test_msg_.states[7].sid.sat, 222); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 42.27101516723633); + assign(test_msg_.states[8].sid.code, 0); + assign(test_msg_.states[8].sid.reserved, 0); + assign(test_msg_.states[8].sid.sat, 225); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].sid.code, 0); + assign(test_msg_.states[9].sid.reserved, 0); + assign(test_msg_.states[9].sid.sat, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].sid.code, 0); + assign(test_msg_.states[10].sid.reserved, 0); + assign(test_msg_.states[10].sid.sat, 0); + assign(test_msg_.states[10].state, 0); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState0, Test) { - uint8_t encoded_frame[] = { - 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 197, 253, 28, - 66, 1, 203, 0, 0, 0, 231, 99, 16, 66, 1, 208, 0, 0, - 0, 212, 129, 22, 66, 1, 212, 0, 0, 0, 58, 21, 28, 66, - 1, 217, 0, 0, 0, 178, 33, 40, 66, 1, 218, 0, 0, 0, - 235, 189, 21, 66, 1, 220, 0, 0, 0, 29, 177, 25, 66, 1, - 222, 0, 0, 0, 43, 169, 27, 66, 1, 225, 0, 0, 0, 137, - 125, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 0, 128, 191, 222, 97, + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; }; - sbp_msg_tracking_state_dep_b_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 39.24782180786133; - test_msg.states[0].sid.code = 0; - test_msg.states[0].sid.reserved = 0; - test_msg.states[0].sid.sat = 202; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 36.09756088256836; - test_msg.states[1].sid.code = 0; - test_msg.states[1].sid.reserved = 0; - test_msg.states[1].sid.sat = 203; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 37.62678527832031; - test_msg.states[2].sid.code = 0; - test_msg.states[2].sid.reserved = 0; - test_msg.states[2].sid.sat = 208; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 39.020729064941406; - test_msg.states[3].sid.code = 0; - test_msg.states[3].sid.reserved = 0; - test_msg.states[3].sid.sat = 212; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 42.03290557861328; - test_msg.states[4].sid.code = 0; - test_msg.states[4].sid.reserved = 0; - test_msg.states[4].sid.sat = 217; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 37.43546676635742; - test_msg.states[5].sid.code = 0; - test_msg.states[5].sid.reserved = 0; - test_msg.states[5].sid.sat = 218; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 38.4229621887207; - test_msg.states[6].sid.code = 0; - test_msg.states[6].sid.reserved = 0; - test_msg.states[6].sid.sat = 220; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 38.91520309448242; - test_msg.states[7].sid.code = 0; - test_msg.states[7].sid.reserved = 0; - test_msg.states[7].sid.sat = 222; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 42.62259292602539; - test_msg.states[8].sid.code = 0; - test_msg.states[8].sid.reserved = 0; - test_msg.states[8].sid.sat = 225; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].sid.code = 0; - test_msg.states[9].sid.reserved = 0; - test_msg.states[9].sid.sat = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].sid.code = 0; - test_msg.states[10].sid.reserved = 0; - test_msg.states[10].sid.sat = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 39.2478218079 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 39.2478218079, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].sid.code, 0) - << "incorrect value for last_msg_.states[0].sid.code, expected 0, is " - << last_msg_.states[0].sid.code; - EXPECT_EQ(last_msg_.states[0].sid.reserved, 0) - << "incorrect value for last_msg_.states[0].sid.reserved, expected 0, is " - << last_msg_.states[0].sid.reserved; - EXPECT_EQ(last_msg_.states[0].sid.sat, 202) - << "incorrect value for last_msg_.states[0].sid.sat, expected 202, is " - << last_msg_.states[0].sid.sat; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 36.0975608826 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 36.0975608826, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].sid.code, 0) - << "incorrect value for last_msg_.states[1].sid.code, expected 0, is " - << last_msg_.states[1].sid.code; - EXPECT_EQ(last_msg_.states[1].sid.reserved, 0) - << "incorrect value for last_msg_.states[1].sid.reserved, expected 0, is " - << last_msg_.states[1].sid.reserved; - EXPECT_EQ(last_msg_.states[1].sid.sat, 203) - << "incorrect value for last_msg_.states[1].sid.sat, expected 203, is " - << last_msg_.states[1].sid.sat; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 37.6267852783 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 37.6267852783, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].sid.code, 0) - << "incorrect value for last_msg_.states[2].sid.code, expected 0, is " - << last_msg_.states[2].sid.code; - EXPECT_EQ(last_msg_.states[2].sid.reserved, 0) - << "incorrect value for last_msg_.states[2].sid.reserved, expected 0, is " - << last_msg_.states[2].sid.reserved; - EXPECT_EQ(last_msg_.states[2].sid.sat, 208) - << "incorrect value for last_msg_.states[2].sid.sat, expected 208, is " - << last_msg_.states[2].sid.sat; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 39.0207290649 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 39.0207290649, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].sid.code, 0) - << "incorrect value for last_msg_.states[3].sid.code, expected 0, is " - << last_msg_.states[3].sid.code; - EXPECT_EQ(last_msg_.states[3].sid.reserved, 0) - << "incorrect value for last_msg_.states[3].sid.reserved, expected 0, is " - << last_msg_.states[3].sid.reserved; - EXPECT_EQ(last_msg_.states[3].sid.sat, 212) - << "incorrect value for last_msg_.states[3].sid.sat, expected 212, is " - << last_msg_.states[3].sid.sat; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 42.0329055786 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 42.0329055786, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].sid.code, 0) - << "incorrect value for last_msg_.states[4].sid.code, expected 0, is " - << last_msg_.states[4].sid.code; - EXPECT_EQ(last_msg_.states[4].sid.reserved, 0) - << "incorrect value for last_msg_.states[4].sid.reserved, expected 0, is " - << last_msg_.states[4].sid.reserved; - EXPECT_EQ(last_msg_.states[4].sid.sat, 217) - << "incorrect value for last_msg_.states[4].sid.sat, expected 217, is " - << last_msg_.states[4].sid.sat; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 37.4354667664 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 37.4354667664, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].sid.code, 0) - << "incorrect value for last_msg_.states[5].sid.code, expected 0, is " - << last_msg_.states[5].sid.code; - EXPECT_EQ(last_msg_.states[5].sid.reserved, 0) - << "incorrect value for last_msg_.states[5].sid.reserved, expected 0, is " - << last_msg_.states[5].sid.reserved; - EXPECT_EQ(last_msg_.states[5].sid.sat, 218) - << "incorrect value for last_msg_.states[5].sid.sat, expected 218, is " - << last_msg_.states[5].sid.sat; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 38.4229621887 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 38.4229621887, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].sid.code, 0) - << "incorrect value for last_msg_.states[6].sid.code, expected 0, is " - << last_msg_.states[6].sid.code; - EXPECT_EQ(last_msg_.states[6].sid.reserved, 0) - << "incorrect value for last_msg_.states[6].sid.reserved, expected 0, is " - << last_msg_.states[6].sid.reserved; - EXPECT_EQ(last_msg_.states[6].sid.sat, 220) - << "incorrect value for last_msg_.states[6].sid.sat, expected 220, is " - << last_msg_.states[6].sid.sat; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 38.9152030945 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 38.9152030945, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].sid.code, 0) - << "incorrect value for last_msg_.states[7].sid.code, expected 0, is " - << last_msg_.states[7].sid.code; - EXPECT_EQ(last_msg_.states[7].sid.reserved, 0) - << "incorrect value for last_msg_.states[7].sid.reserved, expected 0, is " - << last_msg_.states[7].sid.reserved; - EXPECT_EQ(last_msg_.states[7].sid.sat, 222) - << "incorrect value for last_msg_.states[7].sid.sat, expected 222, is " - << last_msg_.states[7].sid.sat; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 42.622592926 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 42.622592926, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].sid.code, 0) - << "incorrect value for last_msg_.states[8].sid.code, expected 0, is " - << last_msg_.states[8].sid.code; - EXPECT_EQ(last_msg_.states[8].sid.reserved, 0) - << "incorrect value for last_msg_.states[8].sid.reserved, expected 0, is " - << last_msg_.states[8].sid.reserved; - EXPECT_EQ(last_msg_.states[8].sid.sat, 225) - << "incorrect value for last_msg_.states[8].sid.sat, expected 225, is " - << last_msg_.states[8].sid.sat; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].sid.code, 0) - << "incorrect value for last_msg_.states[9].sid.code, expected 0, is " - << last_msg_.states[9].sid.code; - EXPECT_EQ(last_msg_.states[9].sid.reserved, 0) - << "incorrect value for last_msg_.states[9].sid.reserved, expected 0, is " - << last_msg_.states[9].sid.reserved; - EXPECT_EQ(last_msg_.states[9].sid.sat, 0) - << "incorrect value for last_msg_.states[9].sid.sat, expected 0, is " - << last_msg_.states[9].sid.sat; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].sid.code, 0) - << "incorrect value for last_msg_.states[10].sid.code, expected 0, is " - << last_msg_.states[10].sid.code; - EXPECT_EQ(last_msg_.states[10].sid.reserved, 0) - << "incorrect value for last_msg_.states[10].sid.reserved, expected 0, " - "is " - << last_msg_.states[10].sid.reserved; - EXPECT_EQ(last_msg_.states[10].sid.sat, 0) - << "incorrect value for last_msg_.states[10].sid.sat, expected 0, is " - << last_msg_.states[10].sid.sat; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgTrackingState1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingState1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState1, Test) { - uint8_t encoded_frame[] = { - 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 250, 249, 27, - 66, 1, 203, 0, 0, 0, 40, 143, 11, 66, 1, 208, 0, 0, - 0, 190, 200, 21, 66, 1, 212, 0, 0, 0, 251, 233, 26, 66, - 1, 217, 0, 0, 0, 209, 238, 39, 66, 1, 218, 0, 0, 0, - 162, 219, 21, 66, 1, 220, 0, 0, 0, 162, 197, 25, 66, 1, - 222, 0, 0, 0, 14, 35, 28, 66, 1, 225, 0, 0, 0, 9, - 153, 43, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 0, 128, 191, 20, 31, + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; }; - sbp_msg_tracking_state_dep_b_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 38.994117736816406; - test_msg.states[0].sid.code = 0; - test_msg.states[0].sid.reserved = 0; - test_msg.states[0].sid.sat = 202; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 34.889801025390625; - test_msg.states[1].sid.code = 0; - test_msg.states[1].sid.reserved = 0; - test_msg.states[1].sid.sat = 203; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 37.44603729248047; - test_msg.states[2].sid.code = 0; - test_msg.states[2].sid.reserved = 0; - test_msg.states[2].sid.sat = 208; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 38.72849655151367; - test_msg.states[3].sid.code = 0; - test_msg.states[3].sid.reserved = 0; - test_msg.states[3].sid.sat = 212; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 41.983219146728516; - test_msg.states[4].sid.code = 0; - test_msg.states[4].sid.reserved = 0; - test_msg.states[4].sid.sat = 217; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 37.46448516845703; - test_msg.states[5].sid.code = 0; - test_msg.states[5].sid.reserved = 0; - test_msg.states[5].sid.sat = 218; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 38.44300079345703; - test_msg.states[6].sid.code = 0; - test_msg.states[6].sid.reserved = 0; - test_msg.states[6].sid.sat = 220; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 39.03423309326172; - test_msg.states[7].sid.code = 0; - test_msg.states[7].sid.reserved = 0; - test_msg.states[7].sid.sat = 222; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 42.89944839477539; - test_msg.states[8].sid.code = 0; - test_msg.states[8].sid.reserved = 0; - test_msg.states[8].sid.sat = 225; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].sid.code = 0; - test_msg.states[9].sid.reserved = 0; - test_msg.states[9].sid.sat = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].sid.code = 0; - test_msg.states[10].sid.reserved = 0; - test_msg.states[10].sid.sat = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 38.9941177368 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 38.9941177368, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].sid.code, 0) - << "incorrect value for last_msg_.states[0].sid.code, expected 0, is " - << last_msg_.states[0].sid.code; - EXPECT_EQ(last_msg_.states[0].sid.reserved, 0) - << "incorrect value for last_msg_.states[0].sid.reserved, expected 0, is " - << last_msg_.states[0].sid.reserved; - EXPECT_EQ(last_msg_.states[0].sid.sat, 202) - << "incorrect value for last_msg_.states[0].sid.sat, expected 202, is " - << last_msg_.states[0].sid.sat; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 34.8898010254 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 34.8898010254, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].sid.code, 0) - << "incorrect value for last_msg_.states[1].sid.code, expected 0, is " - << last_msg_.states[1].sid.code; - EXPECT_EQ(last_msg_.states[1].sid.reserved, 0) - << "incorrect value for last_msg_.states[1].sid.reserved, expected 0, is " - << last_msg_.states[1].sid.reserved; - EXPECT_EQ(last_msg_.states[1].sid.sat, 203) - << "incorrect value for last_msg_.states[1].sid.sat, expected 203, is " - << last_msg_.states[1].sid.sat; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 37.4460372925 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 37.4460372925, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].sid.code, 0) - << "incorrect value for last_msg_.states[2].sid.code, expected 0, is " - << last_msg_.states[2].sid.code; - EXPECT_EQ(last_msg_.states[2].sid.reserved, 0) - << "incorrect value for last_msg_.states[2].sid.reserved, expected 0, is " - << last_msg_.states[2].sid.reserved; - EXPECT_EQ(last_msg_.states[2].sid.sat, 208) - << "incorrect value for last_msg_.states[2].sid.sat, expected 208, is " - << last_msg_.states[2].sid.sat; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 38.7284965515 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 38.7284965515, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].sid.code, 0) - << "incorrect value for last_msg_.states[3].sid.code, expected 0, is " - << last_msg_.states[3].sid.code; - EXPECT_EQ(last_msg_.states[3].sid.reserved, 0) - << "incorrect value for last_msg_.states[3].sid.reserved, expected 0, is " - << last_msg_.states[3].sid.reserved; - EXPECT_EQ(last_msg_.states[3].sid.sat, 212) - << "incorrect value for last_msg_.states[3].sid.sat, expected 212, is " - << last_msg_.states[3].sid.sat; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 41.9832191467 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 41.9832191467, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].sid.code, 0) - << "incorrect value for last_msg_.states[4].sid.code, expected 0, is " - << last_msg_.states[4].sid.code; - EXPECT_EQ(last_msg_.states[4].sid.reserved, 0) - << "incorrect value for last_msg_.states[4].sid.reserved, expected 0, is " - << last_msg_.states[4].sid.reserved; - EXPECT_EQ(last_msg_.states[4].sid.sat, 217) - << "incorrect value for last_msg_.states[4].sid.sat, expected 217, is " - << last_msg_.states[4].sid.sat; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 37.4644851685 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 37.4644851685, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].sid.code, 0) - << "incorrect value for last_msg_.states[5].sid.code, expected 0, is " - << last_msg_.states[5].sid.code; - EXPECT_EQ(last_msg_.states[5].sid.reserved, 0) - << "incorrect value for last_msg_.states[5].sid.reserved, expected 0, is " - << last_msg_.states[5].sid.reserved; - EXPECT_EQ(last_msg_.states[5].sid.sat, 218) - << "incorrect value for last_msg_.states[5].sid.sat, expected 218, is " - << last_msg_.states[5].sid.sat; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 38.4430007935 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 38.4430007935, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].sid.code, 0) - << "incorrect value for last_msg_.states[6].sid.code, expected 0, is " - << last_msg_.states[6].sid.code; - EXPECT_EQ(last_msg_.states[6].sid.reserved, 0) - << "incorrect value for last_msg_.states[6].sid.reserved, expected 0, is " - << last_msg_.states[6].sid.reserved; - EXPECT_EQ(last_msg_.states[6].sid.sat, 220) - << "incorrect value for last_msg_.states[6].sid.sat, expected 220, is " - << last_msg_.states[6].sid.sat; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 39.0342330933 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 39.0342330933, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].sid.code, 0) - << "incorrect value for last_msg_.states[7].sid.code, expected 0, is " - << last_msg_.states[7].sid.code; - EXPECT_EQ(last_msg_.states[7].sid.reserved, 0) - << "incorrect value for last_msg_.states[7].sid.reserved, expected 0, is " - << last_msg_.states[7].sid.reserved; - EXPECT_EQ(last_msg_.states[7].sid.sat, 222) - << "incorrect value for last_msg_.states[7].sid.sat, expected 222, is " - << last_msg_.states[7].sid.sat; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 42.8994483948 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 42.8994483948, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].sid.code, 0) - << "incorrect value for last_msg_.states[8].sid.code, expected 0, is " - << last_msg_.states[8].sid.code; - EXPECT_EQ(last_msg_.states[8].sid.reserved, 0) - << "incorrect value for last_msg_.states[8].sid.reserved, expected 0, is " - << last_msg_.states[8].sid.reserved; - EXPECT_EQ(last_msg_.states[8].sid.sat, 225) - << "incorrect value for last_msg_.states[8].sid.sat, expected 225, is " - << last_msg_.states[8].sid.sat; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].sid.code, 0) - << "incorrect value for last_msg_.states[9].sid.code, expected 0, is " - << last_msg_.states[9].sid.code; - EXPECT_EQ(last_msg_.states[9].sid.reserved, 0) - << "incorrect value for last_msg_.states[9].sid.reserved, expected 0, is " - << last_msg_.states[9].sid.reserved; - EXPECT_EQ(last_msg_.states[9].sid.sat, 0) - << "incorrect value for last_msg_.states[9].sid.sat, expected 0, is " - << last_msg_.states[9].sid.sat; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].sid.code, 0) - << "incorrect value for last_msg_.states[10].sid.code, expected 0, is " - << last_msg_.states[10].sid.code; - EXPECT_EQ(last_msg_.states[10].sid.reserved, 0) - << "incorrect value for last_msg_.states[10].sid.reserved, expected 0, " - "is " - << last_msg_.states[10].sid.reserved; - EXPECT_EQ(last_msg_.states[10].sid.sat, 0) - << "incorrect value for last_msg_.states[10].sid.sat, expected 0, is " - << last_msg_.states[10].sid.sat; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgTrackingState2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingState2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState2, Test) { - uint8_t encoded_frame[] = { - 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 123, 209, 27, - 66, 1, 203, 0, 0, 0, 214, 64, 15, 66, 1, 208, 0, 0, - 0, 56, 55, 22, 66, 1, 212, 0, 0, 0, 91, 142, 27, 66, - 1, 217, 0, 0, 0, 253, 154, 41, 66, 1, 218, 0, 0, 0, - 128, 142, 22, 66, 1, 220, 0, 0, 0, 17, 174, 23, 66, 1, - 222, 0, 0, 0, 155, 2, 29, 66, 1, 225, 0, 0, 0, 162, - 100, 42, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 0, 128, 191, 233, 71, + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_b_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } }; - sbp_msg_tracking_state_dep_b_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 38.95457077026367; - test_msg.states[0].sid.code = 0; - test_msg.states[0].sid.reserved = 0; - test_msg.states[0].sid.sat = 202; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 35.813316345214844; - test_msg.states[1].sid.code = 0; - test_msg.states[1].sid.reserved = 0; - test_msg.states[1].sid.sat = 203; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 37.553924560546875; - test_msg.states[2].sid.code = 0; - test_msg.states[2].sid.reserved = 0; - test_msg.states[2].sid.sat = 208; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 38.88901901245117; - test_msg.states[3].sid.code = 0; - test_msg.states[3].sid.reserved = 0; - test_msg.states[3].sid.sat = 212; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 42.4013557434082; - test_msg.states[4].sid.code = 0; - test_msg.states[4].sid.reserved = 0; - test_msg.states[4].sid.sat = 217; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 37.63916015625; - test_msg.states[5].sid.code = 0; - test_msg.states[5].sid.reserved = 0; - test_msg.states[5].sid.sat = 218; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 37.919986724853516; - test_msg.states[6].sid.code = 0; - test_msg.states[6].sid.reserved = 0; - test_msg.states[6].sid.sat = 220; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 39.25254440307617; - test_msg.states[7].sid.code = 0; - test_msg.states[7].sid.reserved = 0; - test_msg.states[7].sid.sat = 222; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 42.59827423095703; - test_msg.states[8].sid.code = 0; - test_msg.states[8].sid.reserved = 0; - test_msg.states[8].sid.sat = 225; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].sid.code = 0; - test_msg.states[9].sid.reserved = 0; - test_msg.states[9].sid.sat = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].sid.code = 0; - test_msg.states[10].sid.reserved = 0; - test_msg.states[10].sid.sat = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 38.9545707703 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 38.9545707703, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].sid.code, 0) - << "incorrect value for last_msg_.states[0].sid.code, expected 0, is " - << last_msg_.states[0].sid.code; - EXPECT_EQ(last_msg_.states[0].sid.reserved, 0) - << "incorrect value for last_msg_.states[0].sid.reserved, expected 0, is " - << last_msg_.states[0].sid.reserved; - EXPECT_EQ(last_msg_.states[0].sid.sat, 202) - << "incorrect value for last_msg_.states[0].sid.sat, expected 202, is " - << last_msg_.states[0].sid.sat; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 35.8133163452 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 35.8133163452, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].sid.code, 0) - << "incorrect value for last_msg_.states[1].sid.code, expected 0, is " - << last_msg_.states[1].sid.code; - EXPECT_EQ(last_msg_.states[1].sid.reserved, 0) - << "incorrect value for last_msg_.states[1].sid.reserved, expected 0, is " - << last_msg_.states[1].sid.reserved; - EXPECT_EQ(last_msg_.states[1].sid.sat, 203) - << "incorrect value for last_msg_.states[1].sid.sat, expected 203, is " - << last_msg_.states[1].sid.sat; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 37.5539245605 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 37.5539245605, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].sid.code, 0) - << "incorrect value for last_msg_.states[2].sid.code, expected 0, is " - << last_msg_.states[2].sid.code; - EXPECT_EQ(last_msg_.states[2].sid.reserved, 0) - << "incorrect value for last_msg_.states[2].sid.reserved, expected 0, is " - << last_msg_.states[2].sid.reserved; - EXPECT_EQ(last_msg_.states[2].sid.sat, 208) - << "incorrect value for last_msg_.states[2].sid.sat, expected 208, is " - << last_msg_.states[2].sid.sat; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 38.8890190125 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 38.8890190125, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].sid.code, 0) - << "incorrect value for last_msg_.states[3].sid.code, expected 0, is " - << last_msg_.states[3].sid.code; - EXPECT_EQ(last_msg_.states[3].sid.reserved, 0) - << "incorrect value for last_msg_.states[3].sid.reserved, expected 0, is " - << last_msg_.states[3].sid.reserved; - EXPECT_EQ(last_msg_.states[3].sid.sat, 212) - << "incorrect value for last_msg_.states[3].sid.sat, expected 212, is " - << last_msg_.states[3].sid.sat; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 42.4013557434 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 42.4013557434, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].sid.code, 0) - << "incorrect value for last_msg_.states[4].sid.code, expected 0, is " - << last_msg_.states[4].sid.code; - EXPECT_EQ(last_msg_.states[4].sid.reserved, 0) - << "incorrect value for last_msg_.states[4].sid.reserved, expected 0, is " - << last_msg_.states[4].sid.reserved; - EXPECT_EQ(last_msg_.states[4].sid.sat, 217) - << "incorrect value for last_msg_.states[4].sid.sat, expected 217, is " - << last_msg_.states[4].sid.sat; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 37.6391601562 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 37.6391601562, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].sid.code, 0) - << "incorrect value for last_msg_.states[5].sid.code, expected 0, is " - << last_msg_.states[5].sid.code; - EXPECT_EQ(last_msg_.states[5].sid.reserved, 0) - << "incorrect value for last_msg_.states[5].sid.reserved, expected 0, is " - << last_msg_.states[5].sid.reserved; - EXPECT_EQ(last_msg_.states[5].sid.sat, 218) - << "incorrect value for last_msg_.states[5].sid.sat, expected 218, is " - << last_msg_.states[5].sid.sat; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 37.9199867249 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 37.9199867249, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].sid.code, 0) - << "incorrect value for last_msg_.states[6].sid.code, expected 0, is " - << last_msg_.states[6].sid.code; - EXPECT_EQ(last_msg_.states[6].sid.reserved, 0) - << "incorrect value for last_msg_.states[6].sid.reserved, expected 0, is " - << last_msg_.states[6].sid.reserved; - EXPECT_EQ(last_msg_.states[6].sid.sat, 220) - << "incorrect value for last_msg_.states[6].sid.sat, expected 220, is " - << last_msg_.states[6].sid.sat; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 39.2525444031 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 39.2525444031, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].sid.code, 0) - << "incorrect value for last_msg_.states[7].sid.code, expected 0, is " - << last_msg_.states[7].sid.code; - EXPECT_EQ(last_msg_.states[7].sid.reserved, 0) - << "incorrect value for last_msg_.states[7].sid.reserved, expected 0, is " - << last_msg_.states[7].sid.reserved; - EXPECT_EQ(last_msg_.states[7].sid.sat, 222) - << "incorrect value for last_msg_.states[7].sid.sat, expected 222, is " - << last_msg_.states[7].sid.sat; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 42.598274231 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 42.598274231, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].sid.code, 0) - << "incorrect value for last_msg_.states[8].sid.code, expected 0, is " - << last_msg_.states[8].sid.code; - EXPECT_EQ(last_msg_.states[8].sid.reserved, 0) - << "incorrect value for last_msg_.states[8].sid.reserved, expected 0, is " - << last_msg_.states[8].sid.reserved; - EXPECT_EQ(last_msg_.states[8].sid.sat, 225) - << "incorrect value for last_msg_.states[8].sid.sat, expected 225, is " - << last_msg_.states[8].sid.sat; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].sid.code, 0) - << "incorrect value for last_msg_.states[9].sid.code, expected 0, is " - << last_msg_.states[9].sid.code; - EXPECT_EQ(last_msg_.states[9].sid.reserved, 0) - << "incorrect value for last_msg_.states[9].sid.reserved, expected 0, is " - << last_msg_.states[9].sid.reserved; - EXPECT_EQ(last_msg_.states[9].sid.sat, 0) - << "incorrect value for last_msg_.states[9].sid.sat, expected 0, is " - << last_msg_.states[9].sid.sat; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].sid.code, 0) - << "incorrect value for last_msg_.states[10].sid.code, expected 0, is " - << last_msg_.states[10].sid.code; - EXPECT_EQ(last_msg_.states[10].sid.reserved, 0) - << "incorrect value for last_msg_.states[10].sid.reserved, expected 0, " - "is " - << last_msg_.states[10].sid.reserved; - EXPECT_EQ(last_msg_.states[10].sid.sat, 0) - << "incorrect value for last_msg_.states[10].sid.sat, expected 0, is " - << last_msg_.states[10].sid.sat; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgTrackingState3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingState3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepB, + &CHandler::callback_static, this, &node_); + } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + ~CHandler() { sbp_remove_callback(state_, &node_); } -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState3, Test) { - uint8_t encoded_frame[] = { - 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 120, 122, 29, - 66, 1, 203, 0, 0, 0, 66, 22, 18, 66, 1, 208, 0, 0, - 0, 153, 163, 24, 66, 1, 212, 0, 0, 0, 178, 204, 28, 66, - 1, 217, 0, 0, 0, 220, 59, 38, 66, 1, 218, 0, 0, 0, - 161, 27, 20, 66, 1, 220, 0, 0, 0, 125, 107, 24, 66, 1, - 222, 0, 0, 0, 242, 46, 28, 66, 1, 225, 0, 0, 0, 231, - 130, 41, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, - 0, 0, 0, 0, 0, 128, 191, 73, 193, + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_b_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepB); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_b, + sizeof(msg->tracking_state_dep_b)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; }; - sbp_msg_tracking_state_dep_b_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 39.369598388671875; - test_msg.states[0].sid.code = 0; - test_msg.states[0].sid.reserved = 0; - test_msg.states[0].sid.sat = 202; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 36.52173614501953; - test_msg.states[1].sid.code = 0; - test_msg.states[1].sid.reserved = 0; - test_msg.states[1].sid.sat = 203; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 38.15976333618164; - test_msg.states[2].sid.code = 0; - test_msg.states[2].sid.reserved = 0; - test_msg.states[2].sid.sat = 208; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 39.19989776611328; - test_msg.states[3].sid.code = 0; - test_msg.states[3].sid.reserved = 0; - test_msg.states[3].sid.sat = 212; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 41.55845642089844; - test_msg.states[4].sid.code = 0; - test_msg.states[4].sid.reserved = 0; - test_msg.states[4].sid.sat = 217; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 37.026981353759766; - test_msg.states[5].sid.code = 0; - test_msg.states[5].sid.reserved = 0; - test_msg.states[5].sid.sat = 218; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 38.1049690246582; - test_msg.states[6].sid.code = 0; - test_msg.states[6].sid.reserved = 0; - test_msg.states[6].sid.sat = 220; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 39.04584503173828; - test_msg.states[7].sid.code = 0; - test_msg.states[7].sid.reserved = 0; - test_msg.states[7].sid.sat = 222; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 42.37783432006836; - test_msg.states[8].sid.code = 0; - test_msg.states[8].sid.reserved = 0; - test_msg.states[8].sid.sat = 225; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].sid.code = 0; - test_msg.states[9].sid.reserved = 0; - test_msg.states[9].sid.sat = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].sid.code = 0; - test_msg.states[10].sid.reserved = 0; - test_msg.states[10].sid.sat = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 39.3695983887 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 39.3695983887, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].sid.code, 0) - << "incorrect value for last_msg_.states[0].sid.code, expected 0, is " - << last_msg_.states[0].sid.code; - EXPECT_EQ(last_msg_.states[0].sid.reserved, 0) - << "incorrect value for last_msg_.states[0].sid.reserved, expected 0, is " - << last_msg_.states[0].sid.reserved; - EXPECT_EQ(last_msg_.states[0].sid.sat, 202) - << "incorrect value for last_msg_.states[0].sid.sat, expected 202, is " - << last_msg_.states[0].sid.sat; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 36.521736145 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 36.521736145, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].sid.code, 0) - << "incorrect value for last_msg_.states[1].sid.code, expected 0, is " - << last_msg_.states[1].sid.code; - EXPECT_EQ(last_msg_.states[1].sid.reserved, 0) - << "incorrect value for last_msg_.states[1].sid.reserved, expected 0, is " - << last_msg_.states[1].sid.reserved; - EXPECT_EQ(last_msg_.states[1].sid.sat, 203) - << "incorrect value for last_msg_.states[1].sid.sat, expected 203, is " - << last_msg_.states[1].sid.sat; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 38.1597633362 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 38.1597633362, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].sid.code, 0) - << "incorrect value for last_msg_.states[2].sid.code, expected 0, is " - << last_msg_.states[2].sid.code; - EXPECT_EQ(last_msg_.states[2].sid.reserved, 0) - << "incorrect value for last_msg_.states[2].sid.reserved, expected 0, is " - << last_msg_.states[2].sid.reserved; - EXPECT_EQ(last_msg_.states[2].sid.sat, 208) - << "incorrect value for last_msg_.states[2].sid.sat, expected 208, is " - << last_msg_.states[2].sid.sat; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 39.1998977661 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 39.1998977661, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].sid.code, 0) - << "incorrect value for last_msg_.states[3].sid.code, expected 0, is " - << last_msg_.states[3].sid.code; - EXPECT_EQ(last_msg_.states[3].sid.reserved, 0) - << "incorrect value for last_msg_.states[3].sid.reserved, expected 0, is " - << last_msg_.states[3].sid.reserved; - EXPECT_EQ(last_msg_.states[3].sid.sat, 212) - << "incorrect value for last_msg_.states[3].sid.sat, expected 212, is " - << last_msg_.states[3].sid.sat; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 41.5584564209 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 41.5584564209, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].sid.code, 0) - << "incorrect value for last_msg_.states[4].sid.code, expected 0, is " - << last_msg_.states[4].sid.code; - EXPECT_EQ(last_msg_.states[4].sid.reserved, 0) - << "incorrect value for last_msg_.states[4].sid.reserved, expected 0, is " - << last_msg_.states[4].sid.reserved; - EXPECT_EQ(last_msg_.states[4].sid.sat, 217) - << "incorrect value for last_msg_.states[4].sid.sat, expected 217, is " - << last_msg_.states[4].sid.sat; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 37.0269813538 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 37.0269813538, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].sid.code, 0) - << "incorrect value for last_msg_.states[5].sid.code, expected 0, is " - << last_msg_.states[5].sid.code; - EXPECT_EQ(last_msg_.states[5].sid.reserved, 0) - << "incorrect value for last_msg_.states[5].sid.reserved, expected 0, is " - << last_msg_.states[5].sid.reserved; - EXPECT_EQ(last_msg_.states[5].sid.sat, 218) - << "incorrect value for last_msg_.states[5].sid.sat, expected 218, is " - << last_msg_.states[5].sid.sat; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 38.1049690247 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 38.1049690247, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].sid.code, 0) - << "incorrect value for last_msg_.states[6].sid.code, expected 0, is " - << last_msg_.states[6].sid.code; - EXPECT_EQ(last_msg_.states[6].sid.reserved, 0) - << "incorrect value for last_msg_.states[6].sid.reserved, expected 0, is " - << last_msg_.states[6].sid.reserved; - EXPECT_EQ(last_msg_.states[6].sid.sat, 220) - << "incorrect value for last_msg_.states[6].sid.sat, expected 220, is " - << last_msg_.states[6].sid.sat; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 39.0458450317 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 39.0458450317, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].sid.code, 0) - << "incorrect value for last_msg_.states[7].sid.code, expected 0, is " - << last_msg_.states[7].sid.code; - EXPECT_EQ(last_msg_.states[7].sid.reserved, 0) - << "incorrect value for last_msg_.states[7].sid.reserved, expected 0, is " - << last_msg_.states[7].sid.reserved; - EXPECT_EQ(last_msg_.states[7].sid.sat, 222) - << "incorrect value for last_msg_.states[7].sid.sat, expected 222, is " - << last_msg_.states[7].sid.sat; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 42.3778343201 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 42.3778343201, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].sid.code, 0) - << "incorrect value for last_msg_.states[8].sid.code, expected 0, is " - << last_msg_.states[8].sid.code; - EXPECT_EQ(last_msg_.states[8].sid.reserved, 0) - << "incorrect value for last_msg_.states[8].sid.reserved, expected 0, is " - << last_msg_.states[8].sid.reserved; - EXPECT_EQ(last_msg_.states[8].sid.sat, 225) - << "incorrect value for last_msg_.states[8].sid.sat, expected 225, is " - << last_msg_.states[8].sid.sat; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].sid.code, 0) - << "incorrect value for last_msg_.states[9].sid.code, expected 0, is " - << last_msg_.states[9].sid.code; - EXPECT_EQ(last_msg_.states[9].sid.reserved, 0) - << "incorrect value for last_msg_.states[9].sid.reserved, expected 0, is " - << last_msg_.states[9].sid.reserved; - EXPECT_EQ(last_msg_.states[9].sid.sat, 0) - << "incorrect value for last_msg_.states[9].sid.sat, expected 0, is " - << last_msg_.states[9].sid.sat; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].sid.code, 0) - << "incorrect value for last_msg_.states[10].sid.code, expected 0, is " - << last_msg_.states[10].sid.code; - EXPECT_EQ(last_msg_.states[10].sid.reserved, 0) - << "incorrect value for last_msg_.states[10].sid.reserved, expected 0, " - "is " - << last_msg_.states[10].sid.reserved; - EXPECT_EQ(last_msg_.states[10].sid.sat, 0) - << "incorrect value for last_msg_.states[10].sid.sat, expected 0, is " - << last_msg_.states[10].sid.sat; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgTrackingState4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingState4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + struct TestMsgInfo { + sbp_msg_tracking_state_dep_b_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_b, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepB); + info.sender_id = 55286; + info.preamble = 0x55; + info.crc = 0x2f7e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 99; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_b_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_b_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tracking_state_dep_b_t &lesser, + const sbp_msg_tracking_state_dep_b_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_b_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_b_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepB, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState4, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_b_t test_msg_{}; + uint8_t encoded_frame_[99 + 8] = { 85, 19, 0, 246, 215, 99, 1, 202, 0, 0, 0, 103, 208, 30, 66, 1, 203, 0, 0, 0, 117, 24, 18, 66, 1, 208, 0, 0, 0, 200, 173, 20, 66, 1, 212, 0, 0, 0, 137, 68, 27, 66, @@ -1393,264 +4402,678 @@ TEST_F(Test_auto_check_sbp_tracking_MsgTrackingState4, Test) { 21, 41, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 0, 0, 0, 128, 191, 126, 47, }; + uint8_t encoded_payload_[99] = { + 1, 202, 0, 0, 0, 103, 208, 30, 66, 1, 203, 0, 0, 0, 117, 24, 18, 66, + 1, 208, 0, 0, 0, 200, 173, 20, 66, 1, 212, 0, 0, 0, 137, 68, 27, 66, + 1, 217, 0, 0, 0, 243, 51, 40, 66, 1, 218, 0, 0, 0, 225, 58, 23, 66, + 1, 220, 0, 0, 0, 132, 221, 22, 66, 1, 222, 0, 0, 0, 157, 29, 26, 66, + 1, 225, 0, 0, 0, 133, 21, 41, 66, 0, 0, 0, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepB, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + + for (uint8_t i = 0; i < 99; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_b_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepB, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_b_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_b_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } - sbp_msg_tracking_state_dep_b_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 39.70351791381836; - test_msg.states[0].sid.code = 0; - test_msg.states[0].sid.reserved = 0; - test_msg.states[0].sid.sat = 202; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 36.52388381958008; - test_msg.states[1].sid.code = 0; - test_msg.states[1].sid.reserved = 0; - test_msg.states[1].sid.sat = 203; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 37.169708251953125; - test_msg.states[2].sid.code = 0; - test_msg.states[2].sid.reserved = 0; - test_msg.states[2].sid.sat = 208; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 38.81692886352539; - test_msg.states[3].sid.code = 0; - test_msg.states[3].sid.reserved = 0; - test_msg.states[3].sid.sat = 212; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 42.05073165893555; - test_msg.states[4].sid.code = 0; - test_msg.states[4].sid.reserved = 0; - test_msg.states[4].sid.sat = 217; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 37.807498931884766; - test_msg.states[5].sid.code = 0; - test_msg.states[5].sid.reserved = 0; - test_msg.states[5].sid.sat = 218; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 37.71632385253906; - test_msg.states[6].sid.code = 0; - test_msg.states[6].sid.reserved = 0; - test_msg.states[6].sid.sat = 220; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 38.5289192199707; - test_msg.states[7].sid.code = 0; - test_msg.states[7].sid.reserved = 0; - test_msg.states[7].sid.sat = 222; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 42.27101516723633; - test_msg.states[8].sid.code = 0; - test_msg.states[8].sid.reserved = 0; - test_msg.states[8].sid.sat = 225; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].sid.code = 0; - test_msg.states[9].sid.reserved = 0; - test_msg.states[9].sid.sat = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].sid.code = 0; - test_msg.states[10].sid.reserved = 0; - test_msg.states[10].sid.sat = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(55286, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 55286); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 39.7035179138 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 39.7035179138, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].sid.code, 0) - << "incorrect value for last_msg_.states[0].sid.code, expected 0, is " - << last_msg_.states[0].sid.code; - EXPECT_EQ(last_msg_.states[0].sid.reserved, 0) - << "incorrect value for last_msg_.states[0].sid.reserved, expected 0, is " - << last_msg_.states[0].sid.reserved; - EXPECT_EQ(last_msg_.states[0].sid.sat, 202) - << "incorrect value for last_msg_.states[0].sid.sat, expected 202, is " - << last_msg_.states[0].sid.sat; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 36.5238838196 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 36.5238838196, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].sid.code, 0) - << "incorrect value for last_msg_.states[1].sid.code, expected 0, is " - << last_msg_.states[1].sid.code; - EXPECT_EQ(last_msg_.states[1].sid.reserved, 0) - << "incorrect value for last_msg_.states[1].sid.reserved, expected 0, is " - << last_msg_.states[1].sid.reserved; - EXPECT_EQ(last_msg_.states[1].sid.sat, 203) - << "incorrect value for last_msg_.states[1].sid.sat, expected 203, is " - << last_msg_.states[1].sid.sat; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 37.169708252 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 37.169708252, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].sid.code, 0) - << "incorrect value for last_msg_.states[2].sid.code, expected 0, is " - << last_msg_.states[2].sid.code; - EXPECT_EQ(last_msg_.states[2].sid.reserved, 0) - << "incorrect value for last_msg_.states[2].sid.reserved, expected 0, is " - << last_msg_.states[2].sid.reserved; - EXPECT_EQ(last_msg_.states[2].sid.sat, 208) - << "incorrect value for last_msg_.states[2].sid.sat, expected 208, is " - << last_msg_.states[2].sid.sat; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 38.8169288635 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 38.8169288635, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].sid.code, 0) - << "incorrect value for last_msg_.states[3].sid.code, expected 0, is " - << last_msg_.states[3].sid.code; - EXPECT_EQ(last_msg_.states[3].sid.reserved, 0) - << "incorrect value for last_msg_.states[3].sid.reserved, expected 0, is " - << last_msg_.states[3].sid.reserved; - EXPECT_EQ(last_msg_.states[3].sid.sat, 212) - << "incorrect value for last_msg_.states[3].sid.sat, expected 212, is " - << last_msg_.states[3].sid.sat; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 42.0507316589 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 42.0507316589, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].sid.code, 0) - << "incorrect value for last_msg_.states[4].sid.code, expected 0, is " - << last_msg_.states[4].sid.code; - EXPECT_EQ(last_msg_.states[4].sid.reserved, 0) - << "incorrect value for last_msg_.states[4].sid.reserved, expected 0, is " - << last_msg_.states[4].sid.reserved; - EXPECT_EQ(last_msg_.states[4].sid.sat, 217) - << "incorrect value for last_msg_.states[4].sid.sat, expected 217, is " - << last_msg_.states[4].sid.sat; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 37.8074989319 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 37.8074989319, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].sid.code, 0) - << "incorrect value for last_msg_.states[5].sid.code, expected 0, is " - << last_msg_.states[5].sid.code; - EXPECT_EQ(last_msg_.states[5].sid.reserved, 0) - << "incorrect value for last_msg_.states[5].sid.reserved, expected 0, is " - << last_msg_.states[5].sid.reserved; - EXPECT_EQ(last_msg_.states[5].sid.sat, 218) - << "incorrect value for last_msg_.states[5].sid.sat, expected 218, is " - << last_msg_.states[5].sid.sat; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 37.7163238525 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 37.7163238525, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].sid.code, 0) - << "incorrect value for last_msg_.states[6].sid.code, expected 0, is " - << last_msg_.states[6].sid.code; - EXPECT_EQ(last_msg_.states[6].sid.reserved, 0) - << "incorrect value for last_msg_.states[6].sid.reserved, expected 0, is " - << last_msg_.states[6].sid.reserved; - EXPECT_EQ(last_msg_.states[6].sid.sat, 220) - << "incorrect value for last_msg_.states[6].sid.sat, expected 220, is " - << last_msg_.states[6].sid.sat; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 38.52891922 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 38.52891922, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].sid.code, 0) - << "incorrect value for last_msg_.states[7].sid.code, expected 0, is " - << last_msg_.states[7].sid.code; - EXPECT_EQ(last_msg_.states[7].sid.reserved, 0) - << "incorrect value for last_msg_.states[7].sid.reserved, expected 0, is " - << last_msg_.states[7].sid.reserved; - EXPECT_EQ(last_msg_.states[7].sid.sat, 222) - << "incorrect value for last_msg_.states[7].sid.sat, expected 222, is " - << last_msg_.states[7].sid.sat; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 42.2710151672 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 42.2710151672, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].sid.code, 0) - << "incorrect value for last_msg_.states[8].sid.code, expected 0, is " - << last_msg_.states[8].sid.code; - EXPECT_EQ(last_msg_.states[8].sid.reserved, 0) - << "incorrect value for last_msg_.states[8].sid.reserved, expected 0, is " - << last_msg_.states[8].sid.reserved; - EXPECT_EQ(last_msg_.states[8].sid.sat, 225) - << "incorrect value for last_msg_.states[8].sid.sat, expected 225, is " - << last_msg_.states[8].sid.sat; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].sid.code, 0) - << "incorrect value for last_msg_.states[9].sid.code, expected 0, is " - << last_msg_.states[9].sid.code; - EXPECT_EQ(last_msg_.states[9].sid.reserved, 0) - << "incorrect value for last_msg_.states[9].sid.reserved, expected 0, is " - << last_msg_.states[9].sid.reserved; - EXPECT_EQ(last_msg_.states[9].sid.sat, 0) - << "incorrect value for last_msg_.states[9].sid.sat, expected 0, is " - << last_msg_.states[9].sid.sat; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].sid.code, 0) - << "incorrect value for last_msg_.states[10].sid.code, expected 0, is " - << last_msg_.states[10].sid.code; - EXPECT_EQ(last_msg_.states[10].sid.reserved, 0) - << "incorrect value for last_msg_.states[10].sid.reserved, expected 0, " - "is " - << last_msg_.states[10].sid.reserved; - EXPECT_EQ(last_msg_.states[10].sid.sat, 0) - << "incorrect value for last_msg_.states[10].sid.sat, expected 0, is " - << last_msg_.states[10].sid.sat; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; + EXPECT_EQ(sbp_msg_tracking_state_dep_b_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_b_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepB, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.code, greater.states[0].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.reserved, + greater.states[0].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].sid.sat, greater.states[0].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.code, greater.states[1].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.reserved, + greater.states[1].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].sid.sat, greater.states[1].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.code, greater.states[2].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.reserved, + greater.states[2].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].sid.sat, greater.states[2].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.code, greater.states[3].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.reserved, + greater.states[3].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].sid.sat, greater.states[3].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.code, greater.states[4].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.reserved, + greater.states[4].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].sid.sat, greater.states[4].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.code, greater.states[5].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.reserved, + greater.states[5].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].sid.sat, greater.states[5].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.code, greater.states[6].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.reserved, + greater.states[6].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].sid.sat, greater.states[6].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.code, greater.states[7].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.reserved, + greater.states[7].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].sid.sat, greater.states[7].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.code, greater.states[8].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.reserved, + greater.states[8].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].sid.sat, greater.states[8].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.code, greater.states[9].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.reserved, + greater.states[9].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].sid.sat, greater.states[9].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.code, + greater.states[10].sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.reserved, + greater.states[10].sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].sid.sat, greater.states[10].sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_b_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_b_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepB); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_B"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_b_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_b_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_b, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_b, info.test_msg); } + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[99]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 99); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 99), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_b_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 99); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepB, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingState4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepB, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_tracking_MsgTrackingStateDetailedDep.cc b/c/test/cpp/auto_check_sbp_tracking_MsgTrackingStateDetailedDep.cc index a0c3ffd96d..971cb7fa81 100644 --- a/c/test/cpp/auto_check_sbp_tracking_MsgTrackingStateDetailedDep.cc +++ b/c/test/cpp/auto_check_sbp_tracking_MsgTrackingStateDetailedDep.cc @@ -16,893 +16,3811 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0 + : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0() { + assign(test_msg_.L.f, 169); + assign(test_msg_.L.i, 1319); + assign(test_msg_.P, 0); + assign(test_msg_.P_std, 0); + assign(test_msg_.acceleration, 108); + assign(test_msg_.clock_drift, 0); + assign(test_msg_.clock_offset, 0); + assign(test_msg_.cn0, 177); + assign(test_msg_.corr_spacing, 40); + assign(test_msg_.doppler, 15701); + assign(test_msg_.doppler_std, 39); + assign(test_msg_.lock, 14032); + assign(test_msg_.misc_flags, 9); + assign(test_msg_.nav_flags, 0); + assign(test_msg_.pset_flags, 0); + assign(test_msg_.recv_time, 7909447587); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 15); + assign(test_msg_.sync_flags, 1); + assign(test_msg_.tot.tow, 0); + assign(test_msg_.tot.wn, 0); + assign(test_msg_.tow_flags, 0); + assign(test_msg_.track_flags, 11); + assign(test_msg_.uptime, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_tracking_state_detailed_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_tracking_state_detailed_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDetailedDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDetailedDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_detailed_dep, + sizeof(msg->tracking_state_detailed_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_detailed_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_detailed_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDetailedDep); + info.sender_id = 26427; + info.preamble = 0x55; + info.crc = 0xd6a6; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_tracking_state_detailed_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_detailed_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tracking_state_detailed_dep_t &lesser, + const sbp_msg_tracking_state_detailed_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep0, Test) { - uint8_t encoded_frame[] = { + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_detailed_dep_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { 85, 17, 0, 59, 103, 55, 163, 151, 112, 215, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 39, 5, 0, 0, 169, 177, 208, 54, 15, 0, 0, 0, 85, 61, 0, 0, 39, 0, 1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 108, 1, 0, 11, 0, 0, 9, 166, 214, }; + uint8_t encoded_payload_[55] = { + 163, 151, 112, 215, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 39, 5, 0, 0, 169, 177, 208, 54, + 15, 0, 0, 0, 85, 61, 0, 0, 39, 0, 1, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 108, 1, 0, 11, 0, 0, 9, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgTrackingStateDetailedDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgTrackingStateDetailedDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.f, greater.L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.i, greater.L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P, greater.P); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P_std, greater.P_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.acceleration, greater.acceleration); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_drift, greater.clock_drift); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_offset, greater.clock_offset); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corr_spacing, greater.corr_spacing); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler, greater.doppler); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler_std, greater.doppler_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.lock, greater.lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.misc_flags, greater.misc_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.nav_flags, greater.nav_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.pset_flags, greater.pset_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.recv_time, greater.recv_time); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sync_flags, greater.sync_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.tow, greater.tot.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.wn, greater.tot.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tow_flags, greater.tow_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.track_flags, greater.track_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.uptime, greater.uptime); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDetailedDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DETAILED_DEP"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_detailed_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_tracking_state_detailed_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_detailed_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.tracking_state_detailed_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} - sbp_msg_tracking_state_detailed_dep_t test_msg{}; - test_msg.L.f = 169; - test_msg.L.i = 1319; - test_msg.P = 0; - test_msg.P_std = 0; - test_msg.acceleration = 108; - test_msg.clock_drift = 0; - test_msg.clock_offset = 0; - test_msg.cn0 = 177; - test_msg.corr_spacing = 40; - test_msg.doppler = 15701; - test_msg.doppler_std = 39; - test_msg.lock = 14032; - test_msg.misc_flags = 9; - test_msg.nav_flags = 0; - test_msg.pset_flags = 0; - test_msg.recv_time = 7909447587; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 15; - test_msg.sync_flags = 1; - test_msg.tot.tow = 0; - test_msg.tot.wn = 0; - test_msg.tow_flags = 0; - test_msg.track_flags = 11; - test_msg.uptime = 1; - - EXPECT_EQ(send_message(26427, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 26427); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.L.f, 169) - << "incorrect value for last_msg_.L.f, expected 169, is " - << last_msg_.L.f; - EXPECT_EQ(last_msg_.L.i, 1319) - << "incorrect value for last_msg_.L.i, expected 1319, is " - << last_msg_.L.i; - EXPECT_EQ(last_msg_.P, 0) - << "incorrect value for last_msg_.P, expected 0, is " << last_msg_.P; - EXPECT_EQ(last_msg_.P_std, 0) - << "incorrect value for last_msg_.P_std, expected 0, is " - << last_msg_.P_std; - EXPECT_EQ(last_msg_.acceleration, 108) - << "incorrect value for last_msg_.acceleration, expected 108, is " - << last_msg_.acceleration; - EXPECT_EQ(last_msg_.clock_drift, 0) - << "incorrect value for last_msg_.clock_drift, expected 0, is " - << last_msg_.clock_drift; - EXPECT_EQ(last_msg_.clock_offset, 0) - << "incorrect value for last_msg_.clock_offset, expected 0, is " - << last_msg_.clock_offset; - EXPECT_EQ(last_msg_.cn0, 177) - << "incorrect value for last_msg_.cn0, expected 177, is " - << last_msg_.cn0; - EXPECT_EQ(last_msg_.corr_spacing, 40) - << "incorrect value for last_msg_.corr_spacing, expected 40, is " - << last_msg_.corr_spacing; - EXPECT_EQ(last_msg_.doppler, 15701) - << "incorrect value for last_msg_.doppler, expected 15701, is " - << last_msg_.doppler; - EXPECT_EQ(last_msg_.doppler_std, 39) - << "incorrect value for last_msg_.doppler_std, expected 39, is " - << last_msg_.doppler_std; - EXPECT_EQ(last_msg_.lock, 14032) - << "incorrect value for last_msg_.lock, expected 14032, is " - << last_msg_.lock; - EXPECT_EQ(last_msg_.misc_flags, 9) - << "incorrect value for last_msg_.misc_flags, expected 9, is " - << last_msg_.misc_flags; - EXPECT_EQ(last_msg_.nav_flags, 0) - << "incorrect value for last_msg_.nav_flags, expected 0, is " - << last_msg_.nav_flags; - EXPECT_EQ(last_msg_.pset_flags, 0) - << "incorrect value for last_msg_.pset_flags, expected 0, is " - << last_msg_.pset_flags; - EXPECT_EQ(last_msg_.recv_time, 7909447587) - << "incorrect value for last_msg_.recv_time, expected 7909447587, is " - << last_msg_.recv_time; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 15) - << "incorrect value for last_msg_.sid.sat, expected 15, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.sync_flags, 1) - << "incorrect value for last_msg_.sync_flags, expected 1, is " - << last_msg_.sync_flags; - EXPECT_EQ(last_msg_.tot.tow, 0) - << "incorrect value for last_msg_.tot.tow, expected 0, is " - << last_msg_.tot.tow; - EXPECT_EQ(last_msg_.tot.wn, 0) - << "incorrect value for last_msg_.tot.wn, expected 0, is " - << last_msg_.tot.wn; - EXPECT_EQ(last_msg_.tow_flags, 0) - << "incorrect value for last_msg_.tow_flags, expected 0, is " - << last_msg_.tow_flags; - EXPECT_EQ(last_msg_.track_flags, 11) - << "incorrect value for last_msg_.track_flags, expected 11, is " - << last_msg_.track_flags; - EXPECT_EQ(last_msg_.uptime, 1) - << "incorrect value for last_msg_.uptime, expected 1, is " - << last_msg_.uptime; -} -class Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1 + : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1() { + assign(test_msg_.L.f, 14); + assign(test_msg_.L.i, 1810); + assign(test_msg_.P, 0); + assign(test_msg_.P_std, 0); + assign(test_msg_.acceleration, -32); + assign(test_msg_.clock_drift, 0); + assign(test_msg_.clock_offset, 0); + assign(test_msg_.cn0, 175); + assign(test_msg_.corr_spacing, 40); + assign(test_msg_.doppler, 15667); + assign(test_msg_.doppler_std, 30); + assign(test_msg_.lock, 14032); + assign(test_msg_.misc_flags, 9); + assign(test_msg_.nav_flags, 0); + assign(test_msg_.pset_flags, 0); + assign(test_msg_.recv_time, 8409447265); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 15); + assign(test_msg_.sync_flags, 1); + assign(test_msg_.tot.tow, 0); + assign(test_msg_.tot.wn, 0); + assign(test_msg_.tow_flags, 0); + assign(test_msg_.track_flags, 11); + assign(test_msg_.uptime, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_tracking_state_detailed_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_tracking_state_detailed_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDetailedDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDetailedDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_detailed_dep, + sizeof(msg->tracking_state_detailed_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_detailed_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_detailed_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDetailedDep); + info.sender_id = 26427; + info.preamble = 0x55; + info.crc = 0xb388; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; } protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_tracking_state_detailed_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_detailed_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tracking_state_detailed_dep_t &lesser, + const sbp_msg_tracking_state_detailed_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep1, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_tracking_state_detailed_dep_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { 85, 17, 0, 59, 103, 55, 97, 251, 61, 245, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 7, 0, 0, 14, 175, 208, 54, 15, 0, 0, 0, 51, 61, 0, 0, 30, 0, 1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 224, 1, 0, 11, 0, 0, 9, 136, 179, }; + uint8_t encoded_payload_[55] = { + 97, 251, 61, 245, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 18, 7, 0, 0, 14, 175, 208, 54, 15, 0, 0, 0, 51, 61, 0, 0, 30, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 40, 0, 224, 1, 0, 11, 0, 0, 9, + }; +}; - sbp_msg_tracking_state_detailed_dep_t test_msg{}; - test_msg.L.f = 14; - test_msg.L.i = 1810; - test_msg.P = 0; - test_msg.P_std = 0; - test_msg.acceleration = -32; - test_msg.clock_drift = 0; - test_msg.clock_offset = 0; - test_msg.cn0 = 175; - test_msg.corr_spacing = 40; - test_msg.doppler = 15667; - test_msg.doppler_std = 30; - test_msg.lock = 14032; - test_msg.misc_flags = 9; - test_msg.nav_flags = 0; - test_msg.pset_flags = 0; - test_msg.recv_time = 8409447265; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 15; - test_msg.sync_flags = 1; - test_msg.tot.tow = 0; - test_msg.tot.wn = 0; - test_msg.tow_flags = 0; - test_msg.track_flags = 11; - test_msg.uptime = 1; - - EXPECT_EQ(send_message(26427, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 26427); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.L.f, 14) - << "incorrect value for last_msg_.L.f, expected 14, is " << last_msg_.L.f; - EXPECT_EQ(last_msg_.L.i, 1810) - << "incorrect value for last_msg_.L.i, expected 1810, is " - << last_msg_.L.i; - EXPECT_EQ(last_msg_.P, 0) - << "incorrect value for last_msg_.P, expected 0, is " << last_msg_.P; - EXPECT_EQ(last_msg_.P_std, 0) - << "incorrect value for last_msg_.P_std, expected 0, is " - << last_msg_.P_std; - EXPECT_EQ(last_msg_.acceleration, -32) - << "incorrect value for last_msg_.acceleration, expected -32, is " - << last_msg_.acceleration; - EXPECT_EQ(last_msg_.clock_drift, 0) - << "incorrect value for last_msg_.clock_drift, expected 0, is " - << last_msg_.clock_drift; - EXPECT_EQ(last_msg_.clock_offset, 0) - << "incorrect value for last_msg_.clock_offset, expected 0, is " - << last_msg_.clock_offset; - EXPECT_EQ(last_msg_.cn0, 175) - << "incorrect value for last_msg_.cn0, expected 175, is " - << last_msg_.cn0; - EXPECT_EQ(last_msg_.corr_spacing, 40) - << "incorrect value for last_msg_.corr_spacing, expected 40, is " - << last_msg_.corr_spacing; - EXPECT_EQ(last_msg_.doppler, 15667) - << "incorrect value for last_msg_.doppler, expected 15667, is " - << last_msg_.doppler; - EXPECT_EQ(last_msg_.doppler_std, 30) - << "incorrect value for last_msg_.doppler_std, expected 30, is " - << last_msg_.doppler_std; - EXPECT_EQ(last_msg_.lock, 14032) - << "incorrect value for last_msg_.lock, expected 14032, is " - << last_msg_.lock; - EXPECT_EQ(last_msg_.misc_flags, 9) - << "incorrect value for last_msg_.misc_flags, expected 9, is " - << last_msg_.misc_flags; - EXPECT_EQ(last_msg_.nav_flags, 0) - << "incorrect value for last_msg_.nav_flags, expected 0, is " - << last_msg_.nav_flags; - EXPECT_EQ(last_msg_.pset_flags, 0) - << "incorrect value for last_msg_.pset_flags, expected 0, is " - << last_msg_.pset_flags; - EXPECT_EQ(last_msg_.recv_time, 8409447265) - << "incorrect value for last_msg_.recv_time, expected 8409447265, is " - << last_msg_.recv_time; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 15) - << "incorrect value for last_msg_.sid.sat, expected 15, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.sync_flags, 1) - << "incorrect value for last_msg_.sync_flags, expected 1, is " - << last_msg_.sync_flags; - EXPECT_EQ(last_msg_.tot.tow, 0) - << "incorrect value for last_msg_.tot.tow, expected 0, is " - << last_msg_.tot.tow; - EXPECT_EQ(last_msg_.tot.wn, 0) - << "incorrect value for last_msg_.tot.wn, expected 0, is " - << last_msg_.tot.wn; - EXPECT_EQ(last_msg_.tow_flags, 0) - << "incorrect value for last_msg_.tow_flags, expected 0, is " - << last_msg_.tow_flags; - EXPECT_EQ(last_msg_.track_flags, 11) - << "incorrect value for last_msg_.track_flags, expected 11, is " - << last_msg_.track_flags; - EXPECT_EQ(last_msg_.uptime, 1) - << "incorrect value for last_msg_.uptime, expected 1, is " - << last_msg_.uptime; -} -class Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encoded_len(&info.test_msg), + info.payload_len); - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_tracking_state_detailed_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_detailed_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + info.payload_len); +} -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep2, Test) { - uint8_t encoded_frame[] = { - 85, 17, 0, 59, 103, 55, 139, 218, 236, 18, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 8, 0, 0, 8, 179, - 208, 54, 15, 0, 0, 0, 67, 61, 0, 0, 22, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 27, 1, 0, 11, 0, 2, 9, 217, 159, - }; +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; - sbp_msg_tracking_state_detailed_dep_t test_msg{}; - test_msg.L.f = 8; - test_msg.L.i = 2298; - test_msg.P = 0; - test_msg.P_std = 0; - test_msg.acceleration = 27; - test_msg.clock_drift = 0; - test_msg.clock_offset = 0; - test_msg.cn0 = 179; - test_msg.corr_spacing = 40; - test_msg.doppler = 15683; - test_msg.doppler_std = 22; - test_msg.lock = 14032; - test_msg.misc_flags = 9; - test_msg.nav_flags = 0; - test_msg.pset_flags = 2; - test_msg.recv_time = 8907446923; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 15; - test_msg.sync_flags = 1; - test_msg.tot.tow = 0; - test_msg.tot.wn = 0; - test_msg.tow_flags = 0; - test_msg.track_flags = 11; - test_msg.uptime = 2; - - EXPECT_EQ(send_message(26427, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 26427); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.L.f, 8) - << "incorrect value for last_msg_.L.f, expected 8, is " << last_msg_.L.f; - EXPECT_EQ(last_msg_.L.i, 2298) - << "incorrect value for last_msg_.L.i, expected 2298, is " - << last_msg_.L.i; - EXPECT_EQ(last_msg_.P, 0) - << "incorrect value for last_msg_.P, expected 0, is " << last_msg_.P; - EXPECT_EQ(last_msg_.P_std, 0) - << "incorrect value for last_msg_.P_std, expected 0, is " - << last_msg_.P_std; - EXPECT_EQ(last_msg_.acceleration, 27) - << "incorrect value for last_msg_.acceleration, expected 27, is " - << last_msg_.acceleration; - EXPECT_EQ(last_msg_.clock_drift, 0) - << "incorrect value for last_msg_.clock_drift, expected 0, is " - << last_msg_.clock_drift; - EXPECT_EQ(last_msg_.clock_offset, 0) - << "incorrect value for last_msg_.clock_offset, expected 0, is " - << last_msg_.clock_offset; - EXPECT_EQ(last_msg_.cn0, 179) - << "incorrect value for last_msg_.cn0, expected 179, is " - << last_msg_.cn0; - EXPECT_EQ(last_msg_.corr_spacing, 40) - << "incorrect value for last_msg_.corr_spacing, expected 40, is " - << last_msg_.corr_spacing; - EXPECT_EQ(last_msg_.doppler, 15683) - << "incorrect value for last_msg_.doppler, expected 15683, is " - << last_msg_.doppler; - EXPECT_EQ(last_msg_.doppler_std, 22) - << "incorrect value for last_msg_.doppler_std, expected 22, is " - << last_msg_.doppler_std; - EXPECT_EQ(last_msg_.lock, 14032) - << "incorrect value for last_msg_.lock, expected 14032, is " - << last_msg_.lock; - EXPECT_EQ(last_msg_.misc_flags, 9) - << "incorrect value for last_msg_.misc_flags, expected 9, is " - << last_msg_.misc_flags; - EXPECT_EQ(last_msg_.nav_flags, 0) - << "incorrect value for last_msg_.nav_flags, expected 0, is " - << last_msg_.nav_flags; - EXPECT_EQ(last_msg_.pset_flags, 2) - << "incorrect value for last_msg_.pset_flags, expected 2, is " - << last_msg_.pset_flags; - EXPECT_EQ(last_msg_.recv_time, 8907446923) - << "incorrect value for last_msg_.recv_time, expected 8907446923, is " - << last_msg_.recv_time; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 15) - << "incorrect value for last_msg_.sid.sat, expected 15, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.sync_flags, 1) - << "incorrect value for last_msg_.sync_flags, expected 1, is " - << last_msg_.sync_flags; - EXPECT_EQ(last_msg_.tot.tow, 0) - << "incorrect value for last_msg_.tot.tow, expected 0, is " - << last_msg_.tot.tow; - EXPECT_EQ(last_msg_.tot.wn, 0) - << "incorrect value for last_msg_.tot.wn, expected 0, is " - << last_msg_.tot.wn; - EXPECT_EQ(last_msg_.tow_flags, 0) - << "incorrect value for last_msg_.tow_flags, expected 0, is " - << last_msg_.tow_flags; - EXPECT_EQ(last_msg_.track_flags, 11) - << "incorrect value for last_msg_.track_flags, expected 11, is " - << last_msg_.track_flags; - EXPECT_EQ(last_msg_.uptime, 2) - << "incorrect value for last_msg_.uptime, expected 2, is " - << last_msg_.uptime; -} -class Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_tracking_state_detailed_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_detailed_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep3, Test) { - uint8_t encoded_frame[] = { - 85, 17, 0, 59, 103, 55, 255, 251, 170, 48, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 10, 0, 0, 125, 181, - 208, 54, 15, 0, 0, 0, 29, 61, 0, 0, 10, 0, 2, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 220, 1, 0, 11, 0, 3, 9, 66, 95, - }; +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; - sbp_msg_tracking_state_detailed_dep_t test_msg{}; - test_msg.L.f = 125; - test_msg.L.i = 2786; - test_msg.P = 0; - test_msg.P_std = 0; - test_msg.acceleration = -36; - test_msg.clock_drift = 0; - test_msg.clock_offset = 0; - test_msg.cn0 = 181; - test_msg.corr_spacing = 40; - test_msg.doppler = 15645; - test_msg.doppler_std = 10; - test_msg.lock = 14032; - test_msg.misc_flags = 9; - test_msg.nav_flags = 0; - test_msg.pset_flags = 3; - test_msg.recv_time = 9406446591; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 15; - test_msg.sync_flags = 1; - test_msg.tot.tow = 0; - test_msg.tot.wn = 0; - test_msg.tow_flags = 0; - test_msg.track_flags = 11; - test_msg.uptime = 2; - - EXPECT_EQ(send_message(26427, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 26427); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.L.f, 125) - << "incorrect value for last_msg_.L.f, expected 125, is " - << last_msg_.L.f; - EXPECT_EQ(last_msg_.L.i, 2786) - << "incorrect value for last_msg_.L.i, expected 2786, is " - << last_msg_.L.i; - EXPECT_EQ(last_msg_.P, 0) - << "incorrect value for last_msg_.P, expected 0, is " << last_msg_.P; - EXPECT_EQ(last_msg_.P_std, 0) - << "incorrect value for last_msg_.P_std, expected 0, is " - << last_msg_.P_std; - EXPECT_EQ(last_msg_.acceleration, -36) - << "incorrect value for last_msg_.acceleration, expected -36, is " - << last_msg_.acceleration; - EXPECT_EQ(last_msg_.clock_drift, 0) - << "incorrect value for last_msg_.clock_drift, expected 0, is " - << last_msg_.clock_drift; - EXPECT_EQ(last_msg_.clock_offset, 0) - << "incorrect value for last_msg_.clock_offset, expected 0, is " - << last_msg_.clock_offset; - EXPECT_EQ(last_msg_.cn0, 181) - << "incorrect value for last_msg_.cn0, expected 181, is " - << last_msg_.cn0; - EXPECT_EQ(last_msg_.corr_spacing, 40) - << "incorrect value for last_msg_.corr_spacing, expected 40, is " - << last_msg_.corr_spacing; - EXPECT_EQ(last_msg_.doppler, 15645) - << "incorrect value for last_msg_.doppler, expected 15645, is " - << last_msg_.doppler; - EXPECT_EQ(last_msg_.doppler_std, 10) - << "incorrect value for last_msg_.doppler_std, expected 10, is " - << last_msg_.doppler_std; - EXPECT_EQ(last_msg_.lock, 14032) - << "incorrect value for last_msg_.lock, expected 14032, is " - << last_msg_.lock; - EXPECT_EQ(last_msg_.misc_flags, 9) - << "incorrect value for last_msg_.misc_flags, expected 9, is " - << last_msg_.misc_flags; - EXPECT_EQ(last_msg_.nav_flags, 0) - << "incorrect value for last_msg_.nav_flags, expected 0, is " - << last_msg_.nav_flags; - EXPECT_EQ(last_msg_.pset_flags, 3) - << "incorrect value for last_msg_.pset_flags, expected 3, is " - << last_msg_.pset_flags; - EXPECT_EQ(last_msg_.recv_time, 9406446591) - << "incorrect value for last_msg_.recv_time, expected 9406446591, is " - << last_msg_.recv_time; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 15) - << "incorrect value for last_msg_.sid.sat, expected 15, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.sync_flags, 1) - << "incorrect value for last_msg_.sync_flags, expected 1, is " - << last_msg_.sync_flags; - EXPECT_EQ(last_msg_.tot.tow, 0) - << "incorrect value for last_msg_.tot.tow, expected 0, is " - << last_msg_.tot.tow; - EXPECT_EQ(last_msg_.tot.wn, 0) - << "incorrect value for last_msg_.tot.wn, expected 0, is " - << last_msg_.tot.wn; - EXPECT_EQ(last_msg_.tow_flags, 0) - << "incorrect value for last_msg_.tow_flags, expected 0, is " - << last_msg_.tow_flags; - EXPECT_EQ(last_msg_.track_flags, 11) - << "incorrect value for last_msg_.track_flags, expected 11, is " - << last_msg_.track_flags; - EXPECT_EQ(last_msg_.uptime, 2) - << "incorrect value for last_msg_.uptime, expected 2, is " - << last_msg_.uptime; -} -class Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg( - uint16_t sender_id, - const sbp_msg_tracking_state_detailed_dep_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_detailed_dep_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; -TEST_F(Test_auto_check_sbp_tracking_MsgTrackingStateDetailedDep4, Test) { - uint8_t encoded_frame[] = { - 85, 17, 0, 59, 103, 55, 189, 95, 120, 78, 2, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 12, 0, 0, 64, 184, - 208, 54, 15, 0, 0, 0, 24, 61, 0, 0, 4, 0, 3, 0, 0, 0, - 0, 0, 0, 0, 40, 0, 2, 1, 0, 11, 0, 3, 9, 194, 206, - }; + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); - sbp_msg_tracking_state_detailed_dep_t test_msg{}; - test_msg.L.f = 64; - test_msg.L.i = 3275; - test_msg.P = 0; - test_msg.P_std = 0; - test_msg.acceleration = 2; - test_msg.clock_drift = 0; - test_msg.clock_offset = 0; - test_msg.cn0 = 184; - test_msg.corr_spacing = 40; - test_msg.doppler = 15640; - test_msg.doppler_std = 4; - test_msg.lock = 14032; - test_msg.misc_flags = 9; - test_msg.nav_flags = 0; - test_msg.pset_flags = 3; - test_msg.recv_time = 9906446269; - test_msg.sid.code = 0; - test_msg.sid.reserved = 0; - test_msg.sid.sat = 15; - test_msg.sync_flags = 1; - test_msg.tot.tow = 0; - test_msg.tot.wn = 0; - test_msg.tow_flags = 0; - test_msg.track_flags = 11; - test_msg.uptime = 3; - - EXPECT_EQ(send_message(26427, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 26427); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.L.f, 64) - << "incorrect value for last_msg_.L.f, expected 64, is " << last_msg_.L.f; - EXPECT_EQ(last_msg_.L.i, 3275) - << "incorrect value for last_msg_.L.i, expected 3275, is " - << last_msg_.L.i; - EXPECT_EQ(last_msg_.P, 0) - << "incorrect value for last_msg_.P, expected 0, is " << last_msg_.P; - EXPECT_EQ(last_msg_.P_std, 0) - << "incorrect value for last_msg_.P_std, expected 0, is " - << last_msg_.P_std; - EXPECT_EQ(last_msg_.acceleration, 2) - << "incorrect value for last_msg_.acceleration, expected 2, is " - << last_msg_.acceleration; - EXPECT_EQ(last_msg_.clock_drift, 0) - << "incorrect value for last_msg_.clock_drift, expected 0, is " - << last_msg_.clock_drift; - EXPECT_EQ(last_msg_.clock_offset, 0) - << "incorrect value for last_msg_.clock_offset, expected 0, is " - << last_msg_.clock_offset; - EXPECT_EQ(last_msg_.cn0, 184) - << "incorrect value for last_msg_.cn0, expected 184, is " - << last_msg_.cn0; - EXPECT_EQ(last_msg_.corr_spacing, 40) - << "incorrect value for last_msg_.corr_spacing, expected 40, is " - << last_msg_.corr_spacing; - EXPECT_EQ(last_msg_.doppler, 15640) - << "incorrect value for last_msg_.doppler, expected 15640, is " - << last_msg_.doppler; - EXPECT_EQ(last_msg_.doppler_std, 4) - << "incorrect value for last_msg_.doppler_std, expected 4, is " - << last_msg_.doppler_std; - EXPECT_EQ(last_msg_.lock, 14032) - << "incorrect value for last_msg_.lock, expected 14032, is " - << last_msg_.lock; - EXPECT_EQ(last_msg_.misc_flags, 9) - << "incorrect value for last_msg_.misc_flags, expected 9, is " - << last_msg_.misc_flags; - EXPECT_EQ(last_msg_.nav_flags, 0) - << "incorrect value for last_msg_.nav_flags, expected 0, is " - << last_msg_.nav_flags; - EXPECT_EQ(last_msg_.pset_flags, 3) - << "incorrect value for last_msg_.pset_flags, expected 3, is " - << last_msg_.pset_flags; - EXPECT_EQ(last_msg_.recv_time, 9906446269) - << "incorrect value for last_msg_.recv_time, expected 9906446269, is " - << last_msg_.recv_time; - EXPECT_EQ(last_msg_.sid.code, 0) - << "incorrect value for last_msg_.sid.code, expected 0, is " - << last_msg_.sid.code; - EXPECT_EQ(last_msg_.sid.reserved, 0) - << "incorrect value for last_msg_.sid.reserved, expected 0, is " - << last_msg_.sid.reserved; - EXPECT_EQ(last_msg_.sid.sat, 15) - << "incorrect value for last_msg_.sid.sat, expected 15, is " - << last_msg_.sid.sat; - EXPECT_EQ(last_msg_.sync_flags, 1) - << "incorrect value for last_msg_.sync_flags, expected 1, is " - << last_msg_.sync_flags; - EXPECT_EQ(last_msg_.tot.tow, 0) - << "incorrect value for last_msg_.tot.tow, expected 0, is " - << last_msg_.tot.tow; - EXPECT_EQ(last_msg_.tot.wn, 0) - << "incorrect value for last_msg_.tot.wn, expected 0, is " - << last_msg_.tot.wn; - EXPECT_EQ(last_msg_.tow_flags, 0) - << "incorrect value for last_msg_.tow_flags, expected 0, is " - << last_msg_.tow_flags; - EXPECT_EQ(last_msg_.track_flags, 11) - << "incorrect value for last_msg_.track_flags, expected 11, is " - << last_msg_.track_flags; - EXPECT_EQ(last_msg_.uptime, 3) - << "incorrect value for last_msg_.uptime, expected 3, is " - << last_msg_.uptime; + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgTrackingStateDetailedDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); } + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgTrackingStateDetailedDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.f, greater.L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.i, greater.L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P, greater.P); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P_std, greater.P_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.acceleration, greater.acceleration); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_drift, greater.clock_drift); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_offset, greater.clock_offset); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corr_spacing, greater.corr_spacing); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler, greater.doppler); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler_std, greater.doppler_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.lock, greater.lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.misc_flags, greater.misc_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.nav_flags, greater.nav_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.pset_flags, greater.pset_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.recv_time, greater.recv_time); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sync_flags, greater.sync_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.tow, greater.tot.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.wn, greater.tot.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tow_flags, greater.tow_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.track_flags, greater.track_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.uptime, greater.uptime); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDetailedDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DETAILED_DEP"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_detailed_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_tracking_state_detailed_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_detailed_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.tracking_state_detailed_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2() { + assign(test_msg_.L.f, 8); + assign(test_msg_.L.i, 2298); + assign(test_msg_.P, 0); + assign(test_msg_.P_std, 0); + assign(test_msg_.acceleration, 27); + assign(test_msg_.clock_drift, 0); + assign(test_msg_.clock_offset, 0); + assign(test_msg_.cn0, 179); + assign(test_msg_.corr_spacing, 40); + assign(test_msg_.doppler, 15683); + assign(test_msg_.doppler_std, 22); + assign(test_msg_.lock, 14032); + assign(test_msg_.misc_flags, 9); + assign(test_msg_.nav_flags, 0); + assign(test_msg_.pset_flags, 2); + assign(test_msg_.recv_time, 8907446923); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 15); + assign(test_msg_.sync_flags, 1); + assign(test_msg_.tot.tow, 0); + assign(test_msg_.tot.wn, 0); + assign(test_msg_.tow_flags, 0); + assign(test_msg_.track_flags, 11); + assign(test_msg_.uptime, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_tracking_state_detailed_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_tracking_state_detailed_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDetailedDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDetailedDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_detailed_dep, + sizeof(msg->tracking_state_detailed_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_detailed_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_detailed_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDetailedDep); + info.sender_id = 26427; + info.preamble = 0x55; + info.crc = 0x9fd9; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_detailed_dep_t &lesser, + const sbp_msg_tracking_state_detailed_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_detailed_dep_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 17, 0, 59, 103, 55, 139, 218, 236, 18, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 250, 8, 0, 0, 8, 179, + 208, 54, 15, 0, 0, 0, 67, 61, 0, 0, 22, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 27, 1, 0, 11, 0, 2, 9, 217, 159, + }; + uint8_t encoded_payload_[55] = { + 139, 218, 236, 18, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 250, 8, 0, 0, 8, 179, 208, 54, 15, 0, 0, 0, 67, 61, 0, 0, 22, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 40, 0, 27, 1, 0, 11, 0, 2, 9, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgTrackingStateDetailedDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgTrackingStateDetailedDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.f, greater.L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.i, greater.L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P, greater.P); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P_std, greater.P_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.acceleration, greater.acceleration); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_drift, greater.clock_drift); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_offset, greater.clock_offset); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corr_spacing, greater.corr_spacing); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler, greater.doppler); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler_std, greater.doppler_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.lock, greater.lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.misc_flags, greater.misc_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.nav_flags, greater.nav_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.pset_flags, greater.pset_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.recv_time, greater.recv_time); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sync_flags, greater.sync_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.tow, greater.tot.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.wn, greater.tot.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tow_flags, greater.tow_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.track_flags, greater.track_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.uptime, greater.uptime); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDetailedDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DETAILED_DEP"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_detailed_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_tracking_state_detailed_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_detailed_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.tracking_state_detailed_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3() { + assign(test_msg_.L.f, 125); + assign(test_msg_.L.i, 2786); + assign(test_msg_.P, 0); + assign(test_msg_.P_std, 0); + assign(test_msg_.acceleration, -36); + assign(test_msg_.clock_drift, 0); + assign(test_msg_.clock_offset, 0); + assign(test_msg_.cn0, 181); + assign(test_msg_.corr_spacing, 40); + assign(test_msg_.doppler, 15645); + assign(test_msg_.doppler_std, 10); + assign(test_msg_.lock, 14032); + assign(test_msg_.misc_flags, 9); + assign(test_msg_.nav_flags, 0); + assign(test_msg_.pset_flags, 3); + assign(test_msg_.recv_time, 9406446591); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 15); + assign(test_msg_.sync_flags, 1); + assign(test_msg_.tot.tow, 0); + assign(test_msg_.tot.wn, 0); + assign(test_msg_.tow_flags, 0); + assign(test_msg_.track_flags, 11); + assign(test_msg_.uptime, 2); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_tracking_state_detailed_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_tracking_state_detailed_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDetailedDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDetailedDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_detailed_dep, + sizeof(msg->tracking_state_detailed_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_detailed_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_detailed_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDetailedDep); + info.sender_id = 26427; + info.preamble = 0x55; + info.crc = 0x5f42; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_detailed_dep_t &lesser, + const sbp_msg_tracking_state_detailed_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_detailed_dep_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 17, 0, 59, 103, 55, 255, 251, 170, 48, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 10, 0, 0, 125, 181, + 208, 54, 15, 0, 0, 0, 29, 61, 0, 0, 10, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 220, 1, 0, 11, 0, 3, 9, 66, 95, + }; + uint8_t encoded_payload_[55] = { + 255, 251, 170, 48, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 226, 10, 0, 0, 125, 181, 208, 54, + 15, 0, 0, 0, 29, 61, 0, 0, 10, 0, 2, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 220, 1, 0, 11, 0, 3, 9, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgTrackingStateDetailedDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgTrackingStateDetailedDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.f, greater.L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.i, greater.L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P, greater.P); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P_std, greater.P_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.acceleration, greater.acceleration); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_drift, greater.clock_drift); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_offset, greater.clock_offset); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corr_spacing, greater.corr_spacing); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler, greater.doppler); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler_std, greater.doppler_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.lock, greater.lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.misc_flags, greater.misc_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.nav_flags, greater.nav_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.pset_flags, greater.pset_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.recv_time, greater.recv_time); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sync_flags, greater.sync_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.tow, greater.tot.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.wn, greater.tot.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tow_flags, greater.tow_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.track_flags, greater.track_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.uptime, greater.uptime); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDetailedDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DETAILED_DEP"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_detailed_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_tracking_state_detailed_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_detailed_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.tracking_state_detailed_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4() { + assign(test_msg_.L.f, 64); + assign(test_msg_.L.i, 3275); + assign(test_msg_.P, 0); + assign(test_msg_.P_std, 0); + assign(test_msg_.acceleration, 2); + assign(test_msg_.clock_drift, 0); + assign(test_msg_.clock_offset, 0); + assign(test_msg_.cn0, 184); + assign(test_msg_.corr_spacing, 40); + assign(test_msg_.doppler, 15640); + assign(test_msg_.doppler_std, 4); + assign(test_msg_.lock, 14032); + assign(test_msg_.misc_flags, 9); + assign(test_msg_.nav_flags, 0); + assign(test_msg_.pset_flags, 3); + assign(test_msg_.recv_time, 9906446269); + assign(test_msg_.sid.code, 0); + assign(test_msg_.sid.reserved, 0); + assign(test_msg_.sid.sat, 15); + assign(test_msg_.sync_flags, 1); + assign(test_msg_.tot.tow, 0); + assign(test_msg_.tot.wn, 0); + assign(test_msg_.tow_flags, 0); + assign(test_msg_.track_flags, 11); + assign(test_msg_.uptime, 3); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler< + sbp_msg_tracking_state_detailed_dep_t>::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg( + uint16_t sender_id, + const sbp_msg_tracking_state_detailed_dep_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDetailedDep, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_detailed_dep_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDetailedDep); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_detailed_dep, + sizeof(msg->tracking_state_detailed_dep)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_detailed_dep_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_detailed_dep, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDetailedDep); + info.sender_id = 26427; + info.preamble = 0x55; + info.crc = 0xcec2; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 55; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_detailed_dep_t &lesser, + const sbp_msg_tracking_state_detailed_dep_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg( + lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg( + greater); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_detailed_dep_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_detailed_dep_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDetailedDep, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_detailed_dep_t test_msg_{}; + uint8_t encoded_frame_[55 + 8] = { + 85, 17, 0, 59, 103, 55, 189, 95, 120, 78, 2, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 203, 12, 0, 0, 64, 184, + 208, 54, 15, 0, 0, 0, 24, 61, 0, 0, 4, 0, 3, 0, 0, 0, + 0, 0, 0, 0, 40, 0, 2, 1, 0, 11, 0, 3, 9, 194, 206, + }; + uint8_t encoded_payload_[55] = { + 189, 95, 120, 78, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 203, 12, 0, 0, 64, 184, 208, 54, 15, 0, 0, 0, 24, 61, 0, 0, 4, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 40, 0, 2, 1, 0, 11, 0, 3, 9, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode( + &buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], sizeof(buf), + nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + + for (uint8_t i = 0; i < 55; i++) { + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ( + sbp_message_decode(&info.encoded_payload[0], info.payload_len, &n_read, + SbpMsgTrackingStateDetailedDep, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_decode( + &info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_detailed_dep_send( + &state, info.sender_id, &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ( + sbp_message_send(&state, SbpMsgTrackingStateDetailedDep, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.f, greater.L.f); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.L.i, greater.L.i); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P, greater.P); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.P_std, greater.P_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.acceleration, greater.acceleration); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_drift, greater.clock_drift); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.clock_offset, greater.clock_offset); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.cn0, greater.cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.corr_spacing, greater.corr_spacing); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler, greater.doppler); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.doppler_std, greater.doppler_std); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.lock, greater.lock); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.misc_flags, greater.misc_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.nav_flags, greater.nav_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.pset_flags, greater.pset_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.recv_time, greater.recv_time); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.code, greater.sid.code); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.reserved, greater.sid.reserved); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sid.sat, greater.sid.sat); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.sync_flags, greater.sync_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.tow, greater.tot.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tot.wn, greater.tot.wn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.tow_flags, greater.tow_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.track_flags, greater.track_flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_detailed_dep_t lesser = info.test_msg; + sbp_msg_tracking_state_detailed_dep_t greater = info.test_msg; + make_lesser_greater(lesser.uptime, greater.uptime); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDetailedDep); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DETAILED_DEP"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_detailed_dep_t &const_unwrapped = + sbp::MessageTraits::get( + const_sbp_msg_t); + sbp_msg_tracking_state_detailed_dep_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_detailed_dep, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg( + info.test_msg, &msg2); + EXPECT_EQ(msg2.tracking_state_detailed_dep, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ( + sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[55]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 55); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 55), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_detailed_dep_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 55); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgTrackingStateDetailedDep4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDetailedDep, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_tracking_MsgtrackingStateDepA.cc b/c/test/cpp/auto_check_sbp_tracking_MsgtrackingStateDepA.cc index 74e63675e6..3e1551ae46 100644 --- a/c/test/cpp/auto_check_sbp_tracking_MsgtrackingStateDepA.cc +++ b/c/test/cpp/auto_check_sbp_tracking_MsgtrackingStateDepA.cc @@ -16,1401 +16,5093 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_tracking_MsgtrackingStateDepA0 + : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgtrackingStateDepA0() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 11.230907440185547); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 10.438665390014648); + assign(test_msg_.states[1].prn, 2); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 9.732142448425293); + assign(test_msg_.states[2].prn, 3); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 14.341922760009766); + assign(test_msg_.states[3].prn, 7); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 7.8549017906188965); + assign(test_msg_.states[4].prn, 10); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 5.0982866287231445); + assign(test_msg_.states[5].prn, 13); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 6.741272926330566); + assign(test_msg_.states[6].prn, 22); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 12.700549125671387); + assign(test_msg_.states[7].prn, 30); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 15.893081665039062); + assign(test_msg_.states[8].prn, 31); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, 4.242738723754883); + assign(test_msg_.states[9].prn, 25); + assign(test_msg_.states[9].state, 1); + + assign(test_msg_.states[10].cn0, 6.97599983215332); + assign(test_msg_.states[10].prn, 6); + assign(test_msg_.states[10].state, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xe111; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { 85, 22, 0, 195, 4, 66, 1, 0, 204, 177, 51, 65, 1, 2, 198, 4, 39, 65, 1, 3, 219, 182, 27, 65, 1, 7, 132, 120, 101, 65, 1, 10, 91, 91, 251, 64, 1, 13, 42, 37, 163, 64, 1, 22, 130, 184, 215, 64, 1, 30, 115, 53, 75, 65, 1, 31, 16, 74, 126, 65, 1, 25, 132, 196, 135, 64, 1, 6, 100, 59, 223, 64, 17, 225, }; + uint8_t encoded_payload_[66] = { + 1, 0, 204, 177, 51, 65, 1, 2, 198, 4, 39, 65, 1, 3, + 219, 182, 27, 65, 1, 7, 132, 120, 101, 65, 1, 10, 91, 91, + 251, 64, 1, 13, 42, 37, 163, 64, 1, 22, 130, 184, 215, 64, + 1, 30, 115, 53, 75, 65, 1, 31, 16, 74, 126, 65, 1, 25, + 132, 196, 135, 64, 1, 6, 100, 59, 223, 64, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 11.230907440185547; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 10.438665390014648; - test_msg.states[1].prn = 2; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 9.732142448425293; - test_msg.states[2].prn = 3; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 14.341922760009766; - test_msg.states[3].prn = 7; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 7.8549017906188965; - test_msg.states[4].prn = 10; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 5.0982866287231445; - test_msg.states[5].prn = 13; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 6.741272926330566; - test_msg.states[6].prn = 22; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 12.700549125671387; - test_msg.states[7].prn = 30; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 15.893081665039062; - test_msg.states[8].prn = 31; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = 4.242738723754883; - test_msg.states[9].prn = 25; - test_msg.states[9].state = 1; - - test_msg.states[10].cn0 = 6.97599983215332; - test_msg.states[10].prn = 6; - test_msg.states[10].state = 1; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 11.2309074402 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 11.2309074402, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 10.43866539 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 10.43866539, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 2) - << "incorrect value for last_msg_.states[1].prn, expected 2, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 9.73214244843 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 9.73214244843, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 3) - << "incorrect value for last_msg_.states[2].prn, expected 3, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 14.34192276 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 14.34192276, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 7) - << "incorrect value for last_msg_.states[3].prn, expected 7, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 7.85490179062 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 7.85490179062, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 10) - << "incorrect value for last_msg_.states[4].prn, expected 10, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 5.09828662872 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 5.09828662872, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 13) - << "incorrect value for last_msg_.states[5].prn, expected 13, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 6.74127292633 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 6.74127292633, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 22) - << "incorrect value for last_msg_.states[6].prn, expected 22, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 12.7005491257 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 12.7005491257, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 30) - << "incorrect value for last_msg_.states[7].prn, expected 30, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 15.893081665 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 15.893081665, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 31) - << "incorrect value for last_msg_.states[8].prn, expected 31, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - 4.24273872375 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected 4.24273872375, " - "is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 25) - << "incorrect value for last_msg_.states[9].prn, expected 25, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 1) - << "incorrect value for last_msg_.states[9].state, expected 1, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - 6.97599983215 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected " - "6.97599983215, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 6) - << "incorrect value for last_msg_.states[10].prn, expected 6, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 1) - << "incorrect value for last_msg_.states[10].state, expected 1, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA1 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgtrackingStateDepA1 + : public ::testing::Test { public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA1() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Testauto_check_sbp_tracking_MsgtrackingStateDepA1() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 11.014122009277344); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 10.885148048400879); + assign(test_msg_.states[1].prn, 2); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 10.131351470947266); + assign(test_msg_.states[2].prn, 3); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 14.829026222229004); + assign(test_msg_.states[3].prn, 7); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 7.79104471206665); + assign(test_msg_.states[4].prn, 10); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 4.868161201477051); + assign(test_msg_.states[5].prn, 13); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 6.721095561981201); + assign(test_msg_.states[6].prn, 22); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 12.971323013305664); + assign(test_msg_.states[7].prn, 30); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 15.481405258178711); + assign(test_msg_.states[8].prn, 31); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, 3.8834354877471924); + assign(test_msg_.states[9].prn, 25); + assign(test_msg_.states[9].state, 1); + + assign(test_msg_.states[10].cn0, 4.061488628387451); + assign(test_msg_.states[10].prn, 6); + assign(test_msg_.states[10].state, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xada8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA1, Test) { - uint8_t encoded_frame[] = { + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { 85, 22, 0, 195, 4, 66, 1, 0, 216, 57, 48, 65, 1, 2, 145, 41, 46, 65, 1, 3, 4, 26, 34, 65, 1, 7, 177, 67, 109, 65, 1, 10, 61, 80, 249, 64, 1, 13, 250, 199, 155, 64, 1, 22, 55, 19, 215, 64, 1, 30, 138, 138, 79, 65, 1, 31, 214, 179, 119, 65, 1, 25, 53, 138, 120, 64, 1, 6, 183, 247, 129, 64, 168, 173, }; + uint8_t encoded_payload_[66] = { + 1, 0, 216, 57, 48, 65, 1, 2, 145, 41, 46, 65, 1, 3, + 4, 26, 34, 65, 1, 7, 177, 67, 109, 65, 1, 10, 61, 80, + 249, 64, 1, 13, 250, 199, 155, 64, 1, 22, 55, 19, 215, 64, + 1, 30, 138, 138, 79, 65, 1, 31, 214, 179, 119, 65, 1, 25, + 53, 138, 120, 64, 1, 6, 183, 247, 129, 64, + }; +}; - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 11.014122009277344; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 10.885148048400879; - test_msg.states[1].prn = 2; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 10.131351470947266; - test_msg.states[2].prn = 3; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 14.829026222229004; - test_msg.states[3].prn = 7; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 7.79104471206665; - test_msg.states[4].prn = 10; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 4.868161201477051; - test_msg.states[5].prn = 13; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 6.721095561981201; - test_msg.states[6].prn = 22; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 12.971323013305664; - test_msg.states[7].prn = 30; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 15.481405258178711; - test_msg.states[8].prn = 31; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = 3.8834354877471924; - test_msg.states[9].prn = 25; - test_msg.states[9].state = 1; - - test_msg.states[10].cn0 = 4.061488628387451; - test_msg.states[10].prn = 6; - test_msg.states[10].state = 1; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 11.0141220093 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 11.0141220093, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 10.8851480484 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 10.8851480484, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 2) - << "incorrect value for last_msg_.states[1].prn, expected 2, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 10.1313514709 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 10.1313514709, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 3) - << "incorrect value for last_msg_.states[2].prn, expected 3, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 14.8290262222 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 14.8290262222, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 7) - << "incorrect value for last_msg_.states[3].prn, expected 7, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 7.79104471207 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 7.79104471207, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 10) - << "incorrect value for last_msg_.states[4].prn, expected 10, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 4.86816120148 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 4.86816120148, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 13) - << "incorrect value for last_msg_.states[5].prn, expected 13, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 6.72109556198 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 6.72109556198, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 22) - << "incorrect value for last_msg_.states[6].prn, expected 22, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 12.9713230133 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 12.9713230133, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 30) - << "incorrect value for last_msg_.states[7].prn, expected 30, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 15.4814052582 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 15.4814052582, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 31) - << "incorrect value for last_msg_.states[8].prn, expected 31, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - 3.88343548775 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected 3.88343548775, " - "is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 25) - << "incorrect value for last_msg_.states[9].prn, expected 25, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 1) - << "incorrect value for last_msg_.states[9].state, expected 1, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - 4.06148862839 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected " - "4.06148862839, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 6) - << "incorrect value for last_msg_.states[10].prn, expected 6, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 1) - << "incorrect value for last_msg_.states[10].state, expected 1, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA2 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA2() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; - } +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA2, Test) { - uint8_t encoded_frame[] = { - 85, 22, 0, 195, 4, 66, 1, 0, 141, 76, 60, 65, 1, 2, 69, - 139, 46, 65, 1, 3, 146, 27, 30, 65, 1, 7, 235, 56, 97, 65, - 1, 10, 141, 213, 243, 64, 1, 13, 250, 170, 166, 64, 1, 22, 17, - 101, 201, 64, 1, 30, 172, 183, 83, 65, 1, 31, 238, 193, 120, 65, - 1, 25, 220, 48, 132, 64, 1, 6, 49, 214, 54, 64, 110, 179, - }; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 11.768689155578613; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 10.909001350402832; - test_msg.states[1].prn = 2; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 9.881731033325195; - test_msg.states[2].prn = 3; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = 14.076395988464355; - test_msg.states[3].prn = 7; - test_msg.states[3].state = 1; - - test_msg.states[4].cn0 = 7.619818210601807; - test_msg.states[4].prn = 10; - test_msg.states[4].state = 1; - - test_msg.states[5].cn0 = 5.208371162414551; - test_msg.states[5].prn = 13; - test_msg.states[5].state = 1; - - test_msg.states[6].cn0 = 6.2935872077941895; - test_msg.states[6].prn = 22; - test_msg.states[6].state = 1; - - test_msg.states[7].cn0 = 13.232341766357422; - test_msg.states[7].prn = 30; - test_msg.states[7].state = 1; - - test_msg.states[8].cn0 = 15.547346115112305; - test_msg.states[8].prn = 31; - test_msg.states[8].state = 1; - - test_msg.states[9].cn0 = 4.130964279174805; - test_msg.states[9].prn = 25; - test_msg.states[9].state = 1; - - test_msg.states[10].cn0 = 2.856823205947876; - test_msg.states[10].prn = 6; - test_msg.states[10].state = 1; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 11.7686891556 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 11.7686891556, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 10.9090013504 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 10.9090013504, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 2) - << "incorrect value for last_msg_.states[1].prn, expected 2, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 9.88173103333 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 9.88173103333, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 3) - << "incorrect value for last_msg_.states[2].prn, expected 3, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - 14.0763959885 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected 14.0763959885, " - "is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 7) - << "incorrect value for last_msg_.states[3].prn, expected 7, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 1) - << "incorrect value for last_msg_.states[3].state, expected 1, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - 7.6198182106 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected 7.6198182106, " - "is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 10) - << "incorrect value for last_msg_.states[4].prn, expected 10, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 1) - << "incorrect value for last_msg_.states[4].state, expected 1, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - 5.20837116241 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected 5.20837116241, " - "is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 13) - << "incorrect value for last_msg_.states[5].prn, expected 13, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 1) - << "incorrect value for last_msg_.states[5].state, expected 1, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - 6.29358720779 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected 6.29358720779, " - "is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 22) - << "incorrect value for last_msg_.states[6].prn, expected 22, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 1) - << "incorrect value for last_msg_.states[6].state, expected 1, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - 13.2323417664 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected 13.2323417664, " - "is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 30) - << "incorrect value for last_msg_.states[7].prn, expected 30, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 1) - << "incorrect value for last_msg_.states[7].state, expected 1, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - 15.5473461151 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected 15.5473461151, " - "is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 31) - << "incorrect value for last_msg_.states[8].prn, expected 31, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 1) - << "incorrect value for last_msg_.states[8].state, expected 1, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - 4.13096427917 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected 4.13096427917, " - "is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 25) - << "incorrect value for last_msg_.states[9].prn, expected 25, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 1) - << "incorrect value for last_msg_.states[9].state, expected 1, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - 2.85682320595 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected " - "2.85682320595, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 6) - << "incorrect value for last_msg_.states[10].prn, expected 6, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 1) - << "incorrect value for last_msg_.states[10].state, expected 1, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA3 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA3() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA3, Test) { - uint8_t encoded_frame[] = { - 85, 22, 0, 195, 4, 66, 1, 0, 55, 143, 120, 66, 0, 0, 0, - 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, - 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 248, 89, - }; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 62.13985824584961; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = -1.0; - test_msg.states[1].prn = 0; - test_msg.states[1].state = 0; - - test_msg.states[2].cn0 = -1.0; - test_msg.states[2].prn = 0; - test_msg.states[2].state = 0; - - test_msg.states[3].cn0 = -1.0; - test_msg.states[3].prn = 0; - test_msg.states[3].state = 0; - - test_msg.states[4].cn0 = -1.0; - test_msg.states[4].prn = 0; - test_msg.states[4].state = 0; - - test_msg.states[5].cn0 = -1.0; - test_msg.states[5].prn = 0; - test_msg.states[5].state = 0; - - test_msg.states[6].cn0 = -1.0; - test_msg.states[6].prn = 0; - test_msg.states[6].state = 0; - - test_msg.states[7].cn0 = -1.0; - test_msg.states[7].prn = 0; - test_msg.states[7].state = 0; - - test_msg.states[8].cn0 = -1.0; - test_msg.states[8].prn = 0; - test_msg.states[8].state = 0; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].prn = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].prn = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 62.1398582458 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 62.1398582458, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected -1.0, is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 0) - << "incorrect value for last_msg_.states[1].prn, expected 0, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 0) - << "incorrect value for last_msg_.states[1].state, expected 0, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected -1.0, is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 0) - << "incorrect value for last_msg_.states[2].prn, expected 0, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 0) - << "incorrect value for last_msg_.states[2].state, expected 0, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected -1.0, is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 0) - << "incorrect value for last_msg_.states[3].prn, expected 0, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 0) - << "incorrect value for last_msg_.states[3].state, expected 0, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected -1.0, is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 0) - << "incorrect value for last_msg_.states[4].prn, expected 0, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 0) - << "incorrect value for last_msg_.states[4].state, expected 0, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected -1.0, is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 0) - << "incorrect value for last_msg_.states[5].prn, expected 0, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 0) - << "incorrect value for last_msg_.states[5].state, expected 0, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected -1.0, is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 0) - << "incorrect value for last_msg_.states[6].prn, expected 0, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 0) - << "incorrect value for last_msg_.states[6].state, expected 0, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected -1.0, is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 0) - << "incorrect value for last_msg_.states[7].prn, expected 0, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 0) - << "incorrect value for last_msg_.states[7].state, expected 0, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected -1.0, is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 0) - << "incorrect value for last_msg_.states[8].prn, expected 0, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 0) - << "incorrect value for last_msg_.states[8].state, expected 0, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 0) - << "incorrect value for last_msg_.states[9].prn, expected 0, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 0) - << "incorrect value for last_msg_.states[10].prn, expected 0, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA4 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA4() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); } +} - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA4, Test) { - uint8_t encoded_frame[] = { - 85, 22, 0, 195, 4, 66, 1, 0, 218, 14, 19, 66, 1, 2, 210, - 3, 21, 65, 1, 3, 234, 214, 134, 65, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, - 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 84, 101, - }; + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 36.764503479003906; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 9.313432693481445; - test_msg.states[1].prn = 2; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 16.854938507080078; - test_msg.states[2].prn = 3; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = -1.0; - test_msg.states[3].prn = 0; - test_msg.states[3].state = 0; - - test_msg.states[4].cn0 = -1.0; - test_msg.states[4].prn = 0; - test_msg.states[4].state = 0; - - test_msg.states[5].cn0 = -1.0; - test_msg.states[5].prn = 0; - test_msg.states[5].state = 0; - - test_msg.states[6].cn0 = -1.0; - test_msg.states[6].prn = 0; - test_msg.states[6].state = 0; - - test_msg.states[7].cn0 = -1.0; - test_msg.states[7].prn = 0; - test_msg.states[7].state = 0; - - test_msg.states[8].cn0 = -1.0; - test_msg.states[8].prn = 0; - test_msg.states[8].state = 0; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].prn = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].prn = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 36.764503479 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 36.764503479, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 9.31343269348 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 9.31343269348, " - "is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 2) - << "incorrect value for last_msg_.states[1].prn, expected 2, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 16.8549385071 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 16.8549385071, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 3) - << "incorrect value for last_msg_.states[2].prn, expected 3, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected -1.0, is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 0) - << "incorrect value for last_msg_.states[3].prn, expected 0, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 0) - << "incorrect value for last_msg_.states[3].state, expected 0, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected -1.0, is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 0) - << "incorrect value for last_msg_.states[4].prn, expected 0, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 0) - << "incorrect value for last_msg_.states[4].state, expected 0, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected -1.0, is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 0) - << "incorrect value for last_msg_.states[5].prn, expected 0, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 0) - << "incorrect value for last_msg_.states[5].state, expected 0, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected -1.0, is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 0) - << "incorrect value for last_msg_.states[6].prn, expected 0, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 0) - << "incorrect value for last_msg_.states[6].state, expected 0, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected -1.0, is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 0) - << "incorrect value for last_msg_.states[7].prn, expected 0, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 0) - << "incorrect value for last_msg_.states[7].state, expected 0, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected -1.0, is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 0) - << "incorrect value for last_msg_.states[8].prn, expected 0, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 0) - << "incorrect value for last_msg_.states[8].state, expected 0, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 0) - << "incorrect value for last_msg_.states[9].prn, expected 0, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 0) - << "incorrect value for last_msg_.states[10].prn, expected 0, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; -} -class Test_auto_check_sbp_tracking_MsgtrackingStateDepA5 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { - public: - Test_auto_check_sbp_tracking_MsgtrackingStateDepA5() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); - } - - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } - - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); } - protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_tracking_state_dep_a_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; - } - - sbp_msg_tracking_state_dep_a_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} -TEST_F(Test_auto_check_sbp_tracking_MsgtrackingStateDepA5, Test) { - uint8_t encoded_frame[] = { - 85, 22, 0, 195, 4, 66, 1, 0, 98, 39, 219, 65, 1, 2, 0, - 0, 56, 64, 1, 3, 121, 123, 7, 65, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, - 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, - 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 37, 123, - }; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} - sbp_msg_tracking_state_dep_a_t test_msg{}; - test_msg.n_states = 11; - - test_msg.states[0].cn0 = 27.394229888916016; - test_msg.states[0].prn = 0; - test_msg.states[0].state = 1; - - test_msg.states[1].cn0 = 2.875; - test_msg.states[1].prn = 2; - test_msg.states[1].state = 1; - - test_msg.states[2].cn0 = 8.467644691467285; - test_msg.states[2].prn = 3; - test_msg.states[2].state = 1; - - test_msg.states[3].cn0 = -1.0; - test_msg.states[3].prn = 0; - test_msg.states[3].state = 0; - - test_msg.states[4].cn0 = -1.0; - test_msg.states[4].prn = 0; - test_msg.states[4].state = 0; - - test_msg.states[5].cn0 = -1.0; - test_msg.states[5].prn = 0; - test_msg.states[5].state = 0; - - test_msg.states[6].cn0 = -1.0; - test_msg.states[6].prn = 0; - test_msg.states[6].state = 0; - - test_msg.states[7].cn0 = -1.0; - test_msg.states[7].prn = 0; - test_msg.states[7].state = 0; - - test_msg.states[8].cn0 = -1.0; - test_msg.states[8].prn = 0; - test_msg.states[8].state = 0; - - test_msg.states[9].cn0 = -1.0; - test_msg.states[9].prn = 0; - test_msg.states[9].state = 0; - - test_msg.states[10].cn0 = -1.0; - test_msg.states[10].prn = 0; - test_msg.states[10].state = 0; - - EXPECT_EQ(send_message(1219, test_msg), SBP_OK); - - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); - - while (dummy_rd_ < dummy_wr_) { - process(); - } - - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 1219); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.n_states, 11) - << "incorrect value for last_msg_.n_states, expected 11, is " - << last_msg_.n_states; - EXPECT_LT((last_msg_.states[0].cn0 * 100 - 27.3942298889 * 100), 0.05) - << "incorrect value for last_msg_.states[0].cn0, expected 27.3942298889, " - "is " - << last_msg_.states[0].cn0; - EXPECT_EQ(last_msg_.states[0].prn, 0) - << "incorrect value for last_msg_.states[0].prn, expected 0, is " - << last_msg_.states[0].prn; - EXPECT_EQ(last_msg_.states[0].state, 1) - << "incorrect value for last_msg_.states[0].state, expected 1, is " - << last_msg_.states[0].state; - EXPECT_LT((last_msg_.states[1].cn0 * 100 - 2.875 * 100), 0.05) - << "incorrect value for last_msg_.states[1].cn0, expected 2.875, is " - << last_msg_.states[1].cn0; - EXPECT_EQ(last_msg_.states[1].prn, 2) - << "incorrect value for last_msg_.states[1].prn, expected 2, is " - << last_msg_.states[1].prn; - EXPECT_EQ(last_msg_.states[1].state, 1) - << "incorrect value for last_msg_.states[1].state, expected 1, is " - << last_msg_.states[1].state; - EXPECT_LT((last_msg_.states[2].cn0 * 100 - 8.46764469147 * 100), 0.05) - << "incorrect value for last_msg_.states[2].cn0, expected 8.46764469147, " - "is " - << last_msg_.states[2].cn0; - EXPECT_EQ(last_msg_.states[2].prn, 3) - << "incorrect value for last_msg_.states[2].prn, expected 3, is " - << last_msg_.states[2].prn; - EXPECT_EQ(last_msg_.states[2].state, 1) - << "incorrect value for last_msg_.states[2].state, expected 1, is " - << last_msg_.states[2].state; - EXPECT_LT((last_msg_.states[3].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[3].cn0, expected -1.0, is " - << last_msg_.states[3].cn0; - EXPECT_EQ(last_msg_.states[3].prn, 0) - << "incorrect value for last_msg_.states[3].prn, expected 0, is " - << last_msg_.states[3].prn; - EXPECT_EQ(last_msg_.states[3].state, 0) - << "incorrect value for last_msg_.states[3].state, expected 0, is " - << last_msg_.states[3].state; - EXPECT_LT((last_msg_.states[4].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[4].cn0, expected -1.0, is " - << last_msg_.states[4].cn0; - EXPECT_EQ(last_msg_.states[4].prn, 0) - << "incorrect value for last_msg_.states[4].prn, expected 0, is " - << last_msg_.states[4].prn; - EXPECT_EQ(last_msg_.states[4].state, 0) - << "incorrect value for last_msg_.states[4].state, expected 0, is " - << last_msg_.states[4].state; - EXPECT_LT((last_msg_.states[5].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[5].cn0, expected -1.0, is " - << last_msg_.states[5].cn0; - EXPECT_EQ(last_msg_.states[5].prn, 0) - << "incorrect value for last_msg_.states[5].prn, expected 0, is " - << last_msg_.states[5].prn; - EXPECT_EQ(last_msg_.states[5].state, 0) - << "incorrect value for last_msg_.states[5].state, expected 0, is " - << last_msg_.states[5].state; - EXPECT_LT((last_msg_.states[6].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[6].cn0, expected -1.0, is " - << last_msg_.states[6].cn0; - EXPECT_EQ(last_msg_.states[6].prn, 0) - << "incorrect value for last_msg_.states[6].prn, expected 0, is " - << last_msg_.states[6].prn; - EXPECT_EQ(last_msg_.states[6].state, 0) - << "incorrect value for last_msg_.states[6].state, expected 0, is " - << last_msg_.states[6].state; - EXPECT_LT((last_msg_.states[7].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[7].cn0, expected -1.0, is " - << last_msg_.states[7].cn0; - EXPECT_EQ(last_msg_.states[7].prn, 0) - << "incorrect value for last_msg_.states[7].prn, expected 0, is " - << last_msg_.states[7].prn; - EXPECT_EQ(last_msg_.states[7].state, 0) - << "incorrect value for last_msg_.states[7].state, expected 0, is " - << last_msg_.states[7].state; - EXPECT_LT((last_msg_.states[8].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[8].cn0, expected -1.0, is " - << last_msg_.states[8].cn0; - EXPECT_EQ(last_msg_.states[8].prn, 0) - << "incorrect value for last_msg_.states[8].prn, expected 0, is " - << last_msg_.states[8].prn; - EXPECT_EQ(last_msg_.states[8].state, 0) - << "incorrect value for last_msg_.states[8].state, expected 0, is " - << last_msg_.states[8].state; - EXPECT_LT((last_msg_.states[9].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[9].cn0, expected -1.0, is " - << last_msg_.states[9].cn0; - EXPECT_EQ(last_msg_.states[9].prn, 0) - << "incorrect value for last_msg_.states[9].prn, expected 0, is " - << last_msg_.states[9].prn; - EXPECT_EQ(last_msg_.states[9].state, 0) - << "incorrect value for last_msg_.states[9].state, expected 0, is " - << last_msg_.states[9].state; - EXPECT_LT((last_msg_.states[10].cn0 * 100 - -1.0 * 100), 0.05) - << "incorrect value for last_msg_.states[10].cn0, expected -1.0, is " - << last_msg_.states[10].cn0; - EXPECT_EQ(last_msg_.states[10].prn, 0) - << "incorrect value for last_msg_.states[10].prn, expected 0, is " - << last_msg_.states[10].prn; - EXPECT_EQ(last_msg_.states[10].state, 0) - << "incorrect value for last_msg_.states[10].state, expected 0, is " - << last_msg_.states[10].state; +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA1, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgtrackingStateDepA2 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgtrackingStateDepA2() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 11.768689155578613); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 10.909001350402832); + assign(test_msg_.states[1].prn, 2); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 9.881731033325195); + assign(test_msg_.states[2].prn, 3); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, 14.076395988464355); + assign(test_msg_.states[3].prn, 7); + assign(test_msg_.states[3].state, 1); + + assign(test_msg_.states[4].cn0, 7.619818210601807); + assign(test_msg_.states[4].prn, 10); + assign(test_msg_.states[4].state, 1); + + assign(test_msg_.states[5].cn0, 5.208371162414551); + assign(test_msg_.states[5].prn, 13); + assign(test_msg_.states[5].state, 1); + + assign(test_msg_.states[6].cn0, 6.2935872077941895); + assign(test_msg_.states[6].prn, 22); + assign(test_msg_.states[6].state, 1); + + assign(test_msg_.states[7].cn0, 13.232341766357422); + assign(test_msg_.states[7].prn, 30); + assign(test_msg_.states[7].state, 1); + + assign(test_msg_.states[8].cn0, 15.547346115112305); + assign(test_msg_.states[8].prn, 31); + assign(test_msg_.states[8].state, 1); + + assign(test_msg_.states[9].cn0, 4.130964279174805); + assign(test_msg_.states[9].prn, 25); + assign(test_msg_.states[9].state, 1); + + assign(test_msg_.states[10].cn0, 2.856823205947876); + assign(test_msg_.states[10].prn, 6); + assign(test_msg_.states[10].state, 1); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0xb36e; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { + 85, 22, 0, 195, 4, 66, 1, 0, 141, 76, 60, 65, 1, 2, 69, + 139, 46, 65, 1, 3, 146, 27, 30, 65, 1, 7, 235, 56, 97, 65, + 1, 10, 141, 213, 243, 64, 1, 13, 250, 170, 166, 64, 1, 22, 17, + 101, 201, 64, 1, 30, 172, 183, 83, 65, 1, 31, 238, 193, 120, 65, + 1, 25, 220, 48, 132, 64, 1, 6, 49, 214, 54, 64, 110, 179, + }; + uint8_t encoded_payload_[66] = { + 1, 0, 141, 76, 60, 65, 1, 2, 69, 139, 46, 65, 1, 3, + 146, 27, 30, 65, 1, 7, 235, 56, 97, 65, 1, 10, 141, 213, + 243, 64, 1, 13, 250, 170, 166, 64, 1, 22, 17, 101, 201, 64, + 1, 30, 172, 183, 83, 65, 1, 31, 238, 193, 120, 65, 1, 25, + 220, 48, 132, 64, 1, 6, 49, 214, 54, 64, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA2, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgtrackingStateDepA3 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgtrackingStateDepA3() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 62.13985824584961); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, -1.0); + assign(test_msg_.states[1].prn, 0); + assign(test_msg_.states[1].state, 0); + + assign(test_msg_.states[2].cn0, -1.0); + assign(test_msg_.states[2].prn, 0); + assign(test_msg_.states[2].state, 0); + + assign(test_msg_.states[3].cn0, -1.0); + assign(test_msg_.states[3].prn, 0); + assign(test_msg_.states[3].state, 0); + + assign(test_msg_.states[4].cn0, -1.0); + assign(test_msg_.states[4].prn, 0); + assign(test_msg_.states[4].state, 0); + + assign(test_msg_.states[5].cn0, -1.0); + assign(test_msg_.states[5].prn, 0); + assign(test_msg_.states[5].state, 0); + + assign(test_msg_.states[6].cn0, -1.0); + assign(test_msg_.states[6].prn, 0); + assign(test_msg_.states[6].state, 0); + + assign(test_msg_.states[7].cn0, -1.0); + assign(test_msg_.states[7].prn, 0); + assign(test_msg_.states[7].state, 0); + + assign(test_msg_.states[8].cn0, -1.0); + assign(test_msg_.states[8].prn, 0); + assign(test_msg_.states[8].state, 0); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].prn, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].prn, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x59f8; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { + 85, 22, 0, 195, 4, 66, 1, 0, 55, 143, 120, 66, 0, 0, 0, + 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, + 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 248, 89, + }; + uint8_t encoded_payload_[66] = { + 1, 0, 55, 143, 120, 66, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA3, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgtrackingStateDepA4 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgtrackingStateDepA4() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 36.764503479003906); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 9.313432693481445); + assign(test_msg_.states[1].prn, 2); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 16.854938507080078); + assign(test_msg_.states[2].prn, 3); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, -1.0); + assign(test_msg_.states[3].prn, 0); + assign(test_msg_.states[3].state, 0); + + assign(test_msg_.states[4].cn0, -1.0); + assign(test_msg_.states[4].prn, 0); + assign(test_msg_.states[4].state, 0); + + assign(test_msg_.states[5].cn0, -1.0); + assign(test_msg_.states[5].prn, 0); + assign(test_msg_.states[5].state, 0); + + assign(test_msg_.states[6].cn0, -1.0); + assign(test_msg_.states[6].prn, 0); + assign(test_msg_.states[6].state, 0); + + assign(test_msg_.states[7].cn0, -1.0); + assign(test_msg_.states[7].prn, 0); + assign(test_msg_.states[7].state, 0); + + assign(test_msg_.states[8].cn0, -1.0); + assign(test_msg_.states[8].prn, 0); + assign(test_msg_.states[8].state, 0); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].prn, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].prn, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x6554; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { + 85, 22, 0, 195, 4, 66, 1, 0, 218, 14, 19, 66, 1, 2, 210, + 3, 21, 65, 1, 3, 234, 214, 134, 65, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, + 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 84, 101, + }; + uint8_t encoded_payload_[66] = { + 1, 0, 218, 14, 19, 66, 1, 2, 210, 3, 21, 65, 1, 3, 234, 214, 134, 65, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA4, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +class Testauto_check_sbp_tracking_MsgtrackingStateDepA5 + : public ::testing::Test { + public: + Testauto_check_sbp_tracking_MsgtrackingStateDepA5() { + assign(test_msg_.n_states, 11); + + assign(test_msg_.states[0].cn0, 27.394229888916016); + assign(test_msg_.states[0].prn, 0); + assign(test_msg_.states[0].state, 1); + + assign(test_msg_.states[1].cn0, 2.875); + assign(test_msg_.states[1].prn, 2); + assign(test_msg_.states[1].state, 1); + + assign(test_msg_.states[2].cn0, 8.467644691467285); + assign(test_msg_.states[2].prn, 3); + assign(test_msg_.states[2].state, 1); + + assign(test_msg_.states[3].cn0, -1.0); + assign(test_msg_.states[3].prn, 0); + assign(test_msg_.states[3].state, 0); + + assign(test_msg_.states[4].cn0, -1.0); + assign(test_msg_.states[4].prn, 0); + assign(test_msg_.states[4].state, 0); + + assign(test_msg_.states[5].cn0, -1.0); + assign(test_msg_.states[5].prn, 0); + assign(test_msg_.states[5].state, 0); + + assign(test_msg_.states[6].cn0, -1.0); + assign(test_msg_.states[6].prn, 0); + assign(test_msg_.states[6].state, 0); + + assign(test_msg_.states[7].cn0, -1.0); + assign(test_msg_.states[7].prn, 0); + assign(test_msg_.states[7].state, 0); + + assign(test_msg_.states[8].cn0, -1.0); + assign(test_msg_.states[8].prn, 0); + assign(test_msg_.states[8].state, 0); + + assign(test_msg_.states[9].cn0, -1.0); + assign(test_msg_.states[9].prn, 0); + assign(test_msg_.states[9].state, 0); + + assign(test_msg_.states[10].cn0, -1.0); + assign(test_msg_.states[10].prn, 0); + assign(test_msg_.states[10].state, 0); + } + + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final + : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_tracking_state_dep_a_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgTrackingStateDepA, + &CHandler::callback_static, this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_tracking_state_dep_a_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgTrackingStateDepA); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->tracking_state_dep_a, + sizeof(msg->tracking_state_dep_a)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_tracking_state_dep_a_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } + + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.tracking_state_dep_a, &test_msg_, + sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgTrackingStateDepA); + info.sender_id = 1219; + info.preamble = 0x55; + info.crc = 0x7b25; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 66; + + return info; + } + + protected: + void comparison_tests(const sbp_msg_tracking_state_dep_a_t &lesser, + const sbp_msg_tracking_state_dep_a_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_tracking_state_dep_a_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_tracking_state_dep_a_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_lesser), + 0); + EXPECT_EQ(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_greater), + 0); + EXPECT_LE(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_lesser, + &wrapped_greater), + 0); + EXPECT_GT(sbp_message_cmp(SbpMsgTrackingStateDepA, &wrapped_greater, + &wrapped_lesser), + 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } + + private: + sbp_msg_tracking_state_dep_a_t test_msg_{}; + uint8_t encoded_frame_[66 + 8] = { + 85, 22, 0, 195, 4, 66, 1, 0, 98, 39, 219, 65, 1, 2, 0, + 0, 56, 64, 1, 3, 121, 123, 7, 65, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, + 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 37, 123, + }; + uint8_t encoded_payload_[66] = { + 1, 0, 98, 39, 219, 65, 1, 2, 0, 0, 56, 64, 1, 3, 121, 123, 7, 65, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + 0, 0, 0, 0, 128, 191, 0, 0, 0, 0, 128, 191, + }; +}; + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encoded_len(&info.test_msg), + info.payload_len); + + EXPECT_EQ( + sbp_message_encoded_len(SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), + &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, + SbpMsgTrackingStateDepA, &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], sizeof(buf), nullptr, + &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + + for (uint8_t i = 0; i < 66; i++) { + EXPECT_EQ(sbp_msg_tracking_state_dep_a_encode(&buf[0], i, nullptr, + &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); + + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgTrackingStateDepA, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode( + &info.encoded_payload[0], info.payload_len, nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + size_t overhead = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }(); + size_t elem_size = []() -> size_t { + sbp_msg_tracking_state_dep_a_t t{}; + t.n_states = 1; + return sbp_msg_tracking_state_dep_a_encoded_len(&t); + }() - overhead; + + if (i >= overhead) { + if (((i - overhead) % elem_size) == 0) { + expected_return = SBP_OK; + } + } + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_decode(&info.encoded_payload[0], i, + nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_tracking_state_dep_a_send(&state, info.sender_id, + &info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgTrackingStateDepA, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.n_states, greater.n_states); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].cn0, greater.states[0].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].prn, greater.states[0].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[0].state, greater.states[0].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].cn0, greater.states[1].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].prn, greater.states[1].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[1].state, greater.states[1].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].cn0, greater.states[2].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].prn, greater.states[2].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[2].state, greater.states[2].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].cn0, greater.states[3].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].prn, greater.states[3].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[3].state, greater.states[3].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].cn0, greater.states[4].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].prn, greater.states[4].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[4].state, greater.states[4].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].cn0, greater.states[5].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].prn, greater.states[5].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[5].state, greater.states[5].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].cn0, greater.states[6].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].prn, greater.states[6].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[6].state, greater.states[6].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].cn0, greater.states[7].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].prn, greater.states[7].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[7].state, greater.states[7].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].cn0, greater.states[8].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].prn, greater.states[8].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[8].state, greater.states[8].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].cn0, greater.states[9].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].prn, greater.states[9].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[9].state, greater.states[9].state); + comparison_tests(lesser, greater); + } + + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].cn0, greater.states[10].cn0); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].prn, greater.states[10].prn); + comparison_tests(lesser, greater); + } + { + sbp_msg_tracking_state_dep_a_t lesser = info.test_msg; + sbp_msg_tracking_state_dep_a_t greater = info.test_msg; + make_lesser_greater(lesser.states[10].state, greater.states[10].state); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, + // SbpMsgTrackingStateDepA); + EXPECT_STREQ(sbp::MessageTraits::name, + "MSG_TRACKING_STATE_DEP_A"); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_tracking_state_dep_a_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_tracking_state_dep_a_t &non_const_unwrapped = + sbp::MessageTraits::get( + non_const_sbp_msg_t); + + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg( + info.test_msg); + EXPECT_EQ(msg1.tracking_state_dep_a, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, + &msg2); + EXPECT_EQ(msg2.tracking_state_dep_a, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len( + info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[66]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 66); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 66), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_tracking_state_dep_a_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 66); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgTrackingStateDepA, + &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_tracking_MsgtrackingStateDepA5, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, SbpMsgTrackingStateDepA, + info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +} // namespace \ No newline at end of file diff --git a/c/test/cpp/auto_check_sbp_vehicle_MsgOdometry.cc b/c/test/cpp/auto_check_sbp_vehicle_MsgOdometry.cc index 43d07685f7..0e31f75385 100644 --- a/c/test/cpp/auto_check_sbp_vehicle_MsgOdometry.cc +++ b/c/test/cpp/auto_check_sbp_vehicle_MsgOdometry.cc @@ -16,92 +16,570 @@ #include #include -#include #include -#include -class Test_auto_check_sbp_vehicle_MsgOdometry0 - : public ::testing::Test, - public sbp::State, - public sbp::IReader, - public sbp::IWriter, - sbp::MessageHandler { +#include +#include + +namespace { + +template +void assign(T &dest, const U &source) { + dest = static_cast(source); +} +class Testauto_check_sbp_vehicle_MsgOdometry0 : public ::testing::Test { public: - Test_auto_check_sbp_vehicle_MsgOdometry0() - : ::testing::Test(), - sbp::State(), - sbp::IReader(), - sbp::IWriter(), - sbp::MessageHandler(this), - last_msg_(), - last_msg_len_(), - last_sender_id_(), - n_callbacks_logged_(), - dummy_wr_(), - dummy_rd_(), - dummy_buff_() { - set_reader(this); - set_writer(this); + Testauto_check_sbp_vehicle_MsgOdometry0() { + assign(test_msg_.flags, 1); + assign(test_msg_.tow, 8); + assign(test_msg_.velocity, 7); } - s32 read(uint8_t *buf, const uint32_t n) override { - uint32_t real_n = n; - memcpy(buf, dummy_buff_ + dummy_rd_, real_n); - dummy_rd_ += real_n; - return (s32)real_n; - } + class Reader final : public sbp::IReader { + public: + Reader(const uint8_t *buf, uint32_t len) + : sbp::IReader(), buf_{buf}, len_{len} {} + + s32 read(uint8_t *buf, const uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf, buf_ + offset_, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return len_ - offset_; } + + static s32 read_static(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->read(buf, len); + } + + private: + const uint8_t *buf_; + uint32_t len_; + uint32_t offset_{}; + }; + + class Writer final : public sbp::IWriter { + public: + explicit Writer(uint32_t max_len = cMaxLen) + : IWriter(), max_len_{max_len} {} + static constexpr uint32_t cMaxLen = SBP_MAX_FRAME_LEN; + + s32 write(const uint8_t *buf, uint32_t n) override { + if (n == 0) { + return 0; + } + uint32_t real_n = std::min(n, remaining()); + if (real_n == 0) { + return -1; + } + memcpy(buf_ + offset_, buf, real_n); + offset_ += real_n; + return static_cast(real_n); + } + + uint32_t remaining() const noexcept { return max_len_ - offset_; } + + const uint8_t *data() const noexcept { return buf_; } + + uint32_t len() const noexcept { return offset_; } + + static s32 write_static(const uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + static s32 write_c(uint8_t *buf, uint32_t len, void *ctx) { + return static_cast(ctx)->write(buf, len); + } + + private: + uint8_t buf_[cMaxLen]; + uint32_t max_len_; + uint32_t offset_{}; + }; + + struct CppHandler final : public sbp::MessageHandler { + using sbp::MessageHandler::MessageHandler; + + struct Output final { + uint16_t sender_id; + sbp_msg_odometry_t msg; + }; + + std::vector outputs{}; + + protected: + void handle_sbp_msg(uint16_t sender_id, + const sbp_msg_odometry_t &msg) override { + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg, sizeof(msg)); + } + }; + + struct CHandler final { + explicit CHandler(sbp_state_t *state) : state_{state} { + sbp_callback_register(state, SbpMsgOdometry, &CHandler::callback_static, + this, &node_); + } + + ~CHandler() { sbp_remove_callback(state_, &node_); } + + struct Output final { + uint16_t sender_id; + sbp_msg_odometry_t msg; + }; + + std::vector outputs{}; + + private: + void callback(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg) { + ASSERT_EQ(msg_type, SbpMsgOdometry); + outputs.emplace_back(); + outputs.back().sender_id = sender_id; + memcpy(&outputs.back().msg, &msg->odometry, sizeof(msg->odometry)); + } + + static void callback_static(uint16_t sender_id, sbp_msg_type_t msg_type, + const sbp_msg_t *msg, void *ctx) { + static_cast(ctx)->callback(sender_id, msg_type, msg); + } + + sbp_msg_callbacks_node_t node_{}; + sbp_state_t *state_; + }; + + struct TestMsgInfo { + sbp_msg_odometry_t test_msg; + sbp_msg_t test_msg_wrapped; + sbp_msg_type_t msg_type; + uint16_t sender_id; + uint8_t preamble; + uint16_t crc; + const uint8_t *encoded_frame; + uint32_t frame_len; + const uint8_t *encoded_payload; + uint8_t payload_len; + + Reader get_frame_reader() const noexcept { + return Reader{encoded_frame, frame_len}; + } - s32 write(const uint8_t *buf, uint32_t n) override { - uint32_t real_n = n; - memcpy(dummy_buff_ + dummy_wr_, buf, real_n); - dummy_wr_ += real_n; - return (s32)real_n; + Writer get_frame_writer() const noexcept { return Writer{frame_len}; } + }; + + TestMsgInfo get_test_msg_info() const noexcept { + TestMsgInfo info; + memcpy(&info.test_msg, &test_msg_, sizeof(test_msg_)); + memcpy(&info.test_msg_wrapped.odometry, &test_msg_, sizeof(test_msg_)); + info.msg_type = static_cast(SbpMsgOdometry); + info.sender_id = 66; + info.preamble = 0x55; + info.crc = 0x6334; + info.encoded_frame = encoded_frame_; + info.frame_len = sizeof(encoded_frame_); + info.encoded_payload = encoded_payload_; + info.payload_len = 9; + + return info; } protected: - void handle_sbp_msg(uint16_t sender_id, - const sbp_msg_odometry_t &msg) override { - last_msg_ = msg; - last_sender_id_ = sender_id; - n_callbacks_logged_++; + void comparison_tests(const sbp_msg_odometry_t &lesser, + const sbp_msg_odometry_t &greater) { + sbp_msg_t wrapped_lesser = + sbp::MessageTraits::to_sbp_msg(lesser); + sbp_msg_t wrapped_greater = + sbp::MessageTraits::to_sbp_msg(greater); + + EXPECT_EQ(sbp_msg_odometry_cmp(&lesser, &lesser), 0); + EXPECT_EQ(sbp_msg_odometry_cmp(&greater, &greater), 0); + EXPECT_LE(sbp_msg_odometry_cmp(&lesser, &greater), 0); + EXPECT_GT(sbp_msg_odometry_cmp(&greater, &lesser), 0); + + EXPECT_EQ(sbp_message_cmp(SbpMsgOdometry, &wrapped_lesser, &wrapped_lesser), + 0); + EXPECT_EQ( + sbp_message_cmp(SbpMsgOdometry, &wrapped_greater, &wrapped_greater), 0); + EXPECT_LE( + sbp_message_cmp(SbpMsgOdometry, &wrapped_lesser, &wrapped_greater), 0); + EXPECT_GT( + sbp_message_cmp(SbpMsgOdometry, &wrapped_greater, &wrapped_lesser), 0); + + // lesser vs lesser + EXPECT_TRUE(lesser == lesser); + EXPECT_FALSE(lesser != lesser); + EXPECT_FALSE(lesser < lesser); + EXPECT_TRUE(lesser <= lesser); + EXPECT_FALSE(lesser > lesser); + EXPECT_TRUE(lesser >= lesser); + + // greater vs greater + EXPECT_TRUE(greater == greater); + EXPECT_FALSE(greater != greater); + EXPECT_FALSE(greater < greater); + EXPECT_TRUE(greater <= greater); + EXPECT_FALSE(greater > greater); + EXPECT_TRUE(greater >= greater); + + // lesser vs greater + EXPECT_FALSE(lesser == greater); + EXPECT_TRUE(lesser != greater); + EXPECT_TRUE(lesser < greater); + EXPECT_TRUE(lesser <= greater); + EXPECT_FALSE(lesser > greater); + EXPECT_FALSE(lesser >= greater); + + // greater vs lesser + EXPECT_FALSE(greater == lesser); + EXPECT_TRUE(greater != lesser); + EXPECT_FALSE(greater < lesser); + EXPECT_FALSE(greater <= lesser); + EXPECT_TRUE(greater > lesser); + EXPECT_TRUE(greater >= lesser); } - sbp_msg_odometry_t last_msg_; - uint8_t last_msg_len_; - uint16_t last_sender_id_; - size_t n_callbacks_logged_; - uint32_t dummy_wr_; - uint32_t dummy_rd_; - uint8_t dummy_buff_[1024]; -}; + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + if (greater == std::numeric_limits::max()) { + lesser--; + } else { + greater++; + } + } + + template ::value, bool> = true> + void make_lesser_greater(T &lesser, T &greater) { + (void)lesser; + greater += static_cast(1.0); + } + + void make_lesser_greater(sbp_string_t &lesser, sbp_string_t &greater) { + if (greater.data[0] == 'z') { + lesser.data[0]--; + } else { + greater.data[0]++; + } + } + + template + void make_lesser_greater(char (&lesser)[N], char (&greater)[N]) { + if (lesser[0] == 'z') { + lesser[0]--; + } else { + greater[0]++; + } + } -TEST_F(Test_auto_check_sbp_vehicle_MsgOdometry0, Test) { - uint8_t encoded_frame[] = { + private: + sbp_msg_odometry_t test_msg_{}; + uint8_t encoded_frame_[9 + 8] = { 85, 3, 9, 66, 0, 9, 8, 0, 0, 0, 7, 0, 0, 0, 1, 52, 99, }; + uint8_t encoded_payload_[9] = { + 8, 0, 0, 0, 7, 0, 0, 0, 1, + }; +}; + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, EncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp_msg_odometry_encoded_len(&info.test_msg), info.payload_len); + + EXPECT_EQ(sbp_message_encoded_len(SbpMsgOdometry, &info.test_msg_wrapped), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, EncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ( + sbp_msg_odometry_encode(&buf[0], sizeof(buf), &n_written, &info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); + + memset(&buf[0], 0, sizeof(buf)); + EXPECT_EQ(sbp_message_encode(&buf[0], sizeof(buf), &n_written, SbpMsgOdometry, + &info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, EncodeToBufWithoutNwritten) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + EXPECT_EQ( + sbp_msg_odometry_encode(&buf[0], sizeof(buf), nullptr, &info.test_msg), + SBP_OK); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, EncodedToBufUnderflow) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + + for (uint8_t i = 0; i < 9; i++) { + EXPECT_EQ(sbp_msg_odometry_encode(&buf[0], i, nullptr, &info.test_msg), + SBP_ENCODE_ERROR); + } +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, DecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_odometry_t msg{}; + uint8_t n_read; - sbp_msg_odometry_t test_msg{}; - test_msg.flags = 1; - test_msg.tow = 8; - test_msg.velocity = 7; + EXPECT_EQ(sbp_msg_odometry_decode(&info.encoded_payload[0], info.payload_len, + &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); - EXPECT_EQ(send_message(66, test_msg), SBP_OK); + sbp_msg_t wrapped_msg{}; + EXPECT_EQ(sbp_message_decode(&info.encoded_payload[0], info.payload_len, + &n_read, SbpMsgOdometry, &wrapped_msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, DecodeFromBufWithoutNread) { + auto info = get_test_msg_info(); + sbp_msg_odometry_t msg{}; + + EXPECT_EQ(sbp_msg_odometry_decode(&info.encoded_payload[0], info.payload_len, + nullptr, &msg), + SBP_OK); + EXPECT_EQ(msg, info.test_msg); +} +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, DecodeFromBufUnderflow) { + auto info = get_test_msg_info(); + sbp_msg_odometry_t msg{}; + + for (uint8_t i = 0; i < info.payload_len; i++) { + int expected_return = SBP_DECODE_ERROR; + + EXPECT_EQ( + sbp_msg_odometry_decode(&info.encoded_payload[0], i, nullptr, &msg), + expected_return); + } +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, ReceiveThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto reader = info.get_frame_reader(); + sbp_state_set_io_context(&state, &reader); + + CHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(sbp_process(&state, &Reader::read_static), SBP_OK); + } + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, SendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_msg_odometry_send(&state, info.sender_id, &info.test_msg, + &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, SendWrappedThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp_message_send(&state, SbpMsgOdometry, info.sender_id, + &info.test_msg_wrapped, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, Comparison) { + auto info = get_test_msg_info(); + { + sbp_msg_odometry_t lesser = info.test_msg; + sbp_msg_odometry_t greater = info.test_msg; + make_lesser_greater(lesser.flags, greater.flags); + comparison_tests(lesser, greater); + } + { + sbp_msg_odometry_t lesser = info.test_msg; + sbp_msg_odometry_t greater = info.test_msg; + make_lesser_greater(lesser.tow, greater.tow); + comparison_tests(lesser, greater); + } + { + sbp_msg_odometry_t lesser = info.test_msg; + sbp_msg_odometry_t greater = info.test_msg; + make_lesser_greater(lesser.velocity, greater.velocity); + comparison_tests(lesser, greater); + } +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsProperties) { + // EXPECT_EQ(sbp::MessageTraits::id, SbpMsgOdometry); + EXPECT_STREQ(sbp::MessageTraits::name, "MSG_ODOMETRY"); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsFromSbpMsgT) { + auto info = get_test_msg_info(); + + const sbp_msg_t &const_sbp_msg_t = info.test_msg_wrapped; + sbp_msg_t &non_const_sbp_msg_t = info.test_msg_wrapped; + + const sbp_msg_odometry_t &const_unwrapped = + sbp::MessageTraits::get(const_sbp_msg_t); + sbp_msg_odometry_t &non_const_unwrapped = + sbp::MessageTraits::get(non_const_sbp_msg_t); - EXPECT_EQ(dummy_wr_, sizeof(encoded_frame)); - EXPECT_EQ(memcmp(dummy_buff_, encoded_frame, sizeof(encoded_frame)), 0); + EXPECT_EQ((const void *)&const_sbp_msg_t, (const void *)&const_unwrapped); + EXPECT_EQ((void *)&non_const_sbp_msg_t, (void *)&non_const_unwrapped); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsToSbpMsgT) { + auto info = get_test_msg_info(); + + sbp_msg_t msg1 = + sbp::MessageTraits::to_sbp_msg(info.test_msg); + EXPECT_EQ(msg1.odometry, info.test_msg); + + sbp_msg_t msg2; + sbp::MessageTraits::to_sbp_msg(info.test_msg, &msg2); + EXPECT_EQ(msg2.odometry, info.test_msg); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsEncodedLen) { + auto info = get_test_msg_info(); + EXPECT_EQ(sbp::MessageTraits::encoded_len(info.test_msg), + info.payload_len); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsSendThroughSbpState) { + auto info = get_test_msg_info(); + sbp_state_t state; + sbp_state_init(&state); + + auto writer = info.get_frame_writer(); + sbp_state_set_io_context(&state, &writer); + + EXPECT_EQ(sbp::MessageTraits::send( + &state, info.sender_id, info.test_msg, &Writer::write_c), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), &info.encoded_frame[0], writer.len()), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsEncodeToBuf) { + auto info = get_test_msg_info(); + uint8_t buf[9]; + uint8_t n_written; + + EXPECT_EQ(sbp::MessageTraits::encode( + &buf[0], sizeof(buf), &n_written, info.test_msg), + SBP_OK); + EXPECT_EQ(n_written, 9); + EXPECT_EQ(memcmp(&buf[0], info.encoded_payload, 9), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, CppTraitsDecodeFromBuf) { + auto info = get_test_msg_info(); + sbp_msg_odometry_t msg{}; + uint8_t n_read; + + EXPECT_EQ(sbp::MessageTraits::decode( + &info.encoded_payload[0], info.payload_len, &n_read, &msg), + SBP_OK); + EXPECT_EQ(n_read, 9); + EXPECT_EQ(msg, info.test_msg); +} - while (dummy_rd_ < dummy_wr_) { - process(); +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, ReceiveThroughMessageHandler) { + auto info = get_test_msg_info(); + auto reader = info.get_frame_reader(); + + sbp::State state{}; + state.set_reader(&reader); + + CppHandler handler{&state}; + + while (reader.remaining() > 0) { + EXPECT_GE(state.process(), SBP_OK); } - EXPECT_EQ(n_callbacks_logged_, 1); - EXPECT_EQ(last_sender_id_, 66); - EXPECT_EQ(last_msg_, test_msg); - EXPECT_EQ(last_msg_.flags, 1) - << "incorrect value for last_msg_.flags, expected 1, is " - << last_msg_.flags; - EXPECT_EQ(last_msg_.tow, 8) - << "incorrect value for last_msg_.tow, expected 8, is " << last_msg_.tow; - EXPECT_EQ(last_msg_.velocity, 7) - << "incorrect value for last_msg_.velocity, expected 7, is " - << last_msg_.velocity; + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, + ProcessSbpMsgTThroughMessageHandler) { + auto info = get_test_msg_info(); + sbp::State state{}; + CppHandler handler(&state); + + state.process_message(info.sender_id, SbpMsgOdometry, &info.test_msg_wrapped); + + EXPECT_EQ(handler.outputs.size(), 1); + EXPECT_EQ(handler.outputs[0].sender_id, info.sender_id); + EXPECT_EQ(handler.outputs[0].msg, info.test_msg); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, SendThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ(state.send_message(info.sender_id, info.test_msg), SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); +} + +TEST_F(Testauto_check_sbp_vehicle_MsgOdometry0, + SendWrappedSbpMsgTThroughCppState) { + auto info = get_test_msg_info(); + auto writer = info.get_frame_writer(); + + sbp::State state{}; + state.set_writer(&writer); + + EXPECT_EQ( + state.send_message(info.sender_id, SbpMsgOdometry, info.test_msg_wrapped), + SBP_OK); + EXPECT_EQ(writer.len(), info.frame_len); + EXPECT_EQ(memcmp(writer.data(), info.encoded_frame, info.frame_len), 0); } + +} // namespace \ No newline at end of file